Introduction

Preventing unintended pregnancy is critical for individual well-being and public health. Unprotected sex occurs for multiple, complex reasons including sexual assault, reproductive coercion, contraceptive mishaps, and lapses in contraceptive use (1). Emergency contraception prevents pregnancy following unprotected sex or contraceptive failure. In Scotland emergency contraception is available as either a pill or intrauterine device. Oral contraceptives are the most commonly used, making up 90% of emergency contraceptive prescriptions (2).

Pharmacies in Scotland dispense two types of emergency contraceptive pills (ECP):

  • Levonorgestrel (brand name: Levonelle) - Effective within 72 hours (three days) of unprotected sex
  • Ulipristal Acetate (brand name: ellaOne) - Effective within 120 hours (five days) of unprotected sex

This analysis explores the factors influencing prescribing trends for ECP in Scotland from 2019 to 2022, using data from the Public Health Scotland Community Prescriptions Database. By investigating ECP patterns over time, geography and socioeconomic status, this report aims to identify disparities in access and inform strategies to improve public health outcomes.

The analysis addresses the following questions:

  1. What are the trends in prescribing of ECP between 2019 and 2022?
  2. How does the ECP prescription rate vary by Health Board regions in Scotland?
  3. Are pharmacies in more deprived areas prescribing more ECP than those in affluent areas?
  4. Is there geographical variation in prescribing practices of ECP by Health Board region?

Load necessary libraries:

library(tidyverse)
library(janitor) 
library(gt) 
library(here)
library(lubridate)
library(sf)
library(ggspatial)
library(plotly)

Read in datasets:

# Read in the Health Board names (HB_names). See code for link.
HB_names <- read_csv("https://www.opendata.nhs.scot/dataset/9f942fdb-e59e-44f5-b534-d6e17229cc7b/resource/652ff726-e676-4a20-abda-435b98dd7bdc/download/hb14_hb19.csv") %>% 
  clean_names() # ensures column names are unique, lower case and spaces and special characters are replaced with underscores. I will use this function for all read ins to ensure my data is consistent and easy to manipulate.

# Read in population data per Health Board from the 2022 census data. Available from: https://statistics.ukdataservice.ac.uk/dataset/scotland-s-census-2022-uv102a-age-by-sex/resource/b2d295c2-af53-4b3d-a075-7815cadd9060 
all_population_data <- read_csv(here("data", "UV103_age_health_board_census.csv"), skip = 10) %>% # locates the csv and excludes the first 10 lines in the csv as they are redundant
  rename(Spare = "...6", # remove unused columns
         hb_name = "Health Board Area 2019",
         hb_population = Count) %>% # rename() formats the data to match the prescriptions dataframe
  filter(Sex == "Female") %>% # filter female population, as men do not take ECP
  select(hb_name, Age, hb_population) %>% # select columns of interest
  mutate(hb_name = paste("NHS", hb_name)) %>%  # change hb_name column format to match the Health Board dataframe format
  clean_names()

# filter dataset for the total female population for each health board:
population_data <- all_population_data %>% 
  filter(age == "All people") %>% 
  select(hb_name, hb_population)

# select the population aged 16 to 34 years as this is the population the population most likely engaging with risk taking behaviors such as unprotected sex. I chose 16 as this is the age of consent in Scotland, and 34 as my cut off for young adults. 
young_population_data <- all_population_data %>% 
  filter(age%in% c(16:34)) %>% # filter ages of interest
  mutate(age = as.numeric(age)) %>% # make numerical so they can be placed in to buckets
  mutate(age_group = case_when(between(age, 16,34)~'16-34')) %>% # make bucket 16-34 years
  group_by(hb_name, age_group) %>% 
  summarise(pop_hb_16_34 = sum(hb_population)) # sum total population aged 16 to 34 per health board region. 

Define a function to read in the prescription data for a defined year:

#For efficiency I created a function to read in the prescriptions datasets. I downloaded 12 months of prescription data for each year from 2019 to 2022. I placed the 12 months of data into their relevant folder named all_months_year, where year was specific to the data it contained.
read_all_prescriptions <- function(year){
  all_files <- list.files(here("data", paste0("all_months_", year)), pattern = "csv") #list.files() retrieves files from the relevant directory, and the paste0() dynamically constructs the folder name based on the year variable placed into the function.
  all_prescriptions <- all_files %>%
    map_dfr(~read_csv(here("data", paste0("all_months_", year),.))) %>% #map_dfr() row-binds the datasets being read in
    clean_names() %>%
    drop_na(bnf_item_description) # drop the rows with missing bnf_item values
  return(all_prescriptions)}

Read in datasets using read_all_prescriptions() function and start data wrangling:

# all_prescriptions_2019 <- read_all_prescriptions(2019)
# all_prescriptions_2020 <- read_all_prescriptions(2020)
# all_prescriptions_2021 <- read_all_prescriptions(2021)
# all_prescriptions_2022 <- read_all_prescriptions(2022)
# 
# # 2019 dataset has hbt2014 as a column name instead of hbt. Rename to make column name consistent
# all_prescriptions_2019 <- all_prescriptions_2019 %>%
#   rename(hbt = "hbt2014")
# 
# # combine 4 years of data into one dataset to make it easier to wrangle
# combined_prescriptions <- bind_rows(
#   all_prescriptions_2019,
#   all_prescriptions_2020,
#   all_prescriptions_2021,
#   all_prescriptions_2022 )%>% # I mutate and select the prescriptions of interest to prevent a very large dataset from being stored in my environment (prevents R slowing down and crashing)
#   mutate(
#     date = parse_date_time(paid_date_month, "ym"), # use lubridate to format date
#     drug_simple = case_when(
#       str_detect(bnf_item_description, "LEVONO") ~ "Levonorgestrel",
#       str_detect(bnf_item_description, "ULIPR") ~ "Ulipristal Acetate",
#       TRUE ~ "Other")) %>% # used case_when() to select ECP even when they have different dosages
#   filter(drug_simple != "Other",!is.na(date)) %>% #remove prescriptions of no interest and any missing date values
#   filter(hbt != "SB0806") %>% # filter out SB0806 as it is not a health board (Scottish Ambulance Service)
#   filter(!is.na(hbt))

# save combined_prescriptions dataset to a csv in my directory, to prevent many large datasets being stored in my environment and slowing down R. 
# write_csv(combined_prescriptions,"data/combined_prescriptions.csv")
combined_prescriptions <- read_csv(here("data","combined_prescriptions.csv"))

Join and wrangle data naming the output variable ECP_scripts:

# join the prescriptions dataset to the Health Board names and health board population datasets
ECP_scripts <- combined_prescriptions %>% 
  full_join(HB_names, by = c("hbt" = "hb")) %>% # join with Health Board names
  full_join(population_data, by = "hb_name") %>% # join with population data
  select(gp_practice, date, drug = drug_simple, hb_name, paid_quantity,hb_population) %>%  # select columns of interest
  mutate(month = factor(month(date), levels = 1:12, labels = month.abb), .after = date) %>%   
  mutate(year = factor(year(date)), .after = month) # extract month and year as a factor with labels to help when plotting

Key Results

How does the ECP prescription rate vary by Health Board regions in Scotland?

Wrangle data to get the columns and values of interest:

ECP_anual_rate_data <- ECP_scripts %>% 
  group_by(hb_name, drug) %>% # aggregate data by Health Board and drug
  summarise(total_quantity_4_years = sum(paid_quantity, na.rm = TRUE), # total prescriptions over 4 years
    avg_annual_total_quantity = total_quantity_4_years / 4, # average annual prescriptions
    hb_population = first(hb_population), # hb_population is consistent within each hb_name
    .groups = "drop") %>% # ungroup data
  drop_na(drug) %>% # remove rows with no drug values
  mutate(avg_annual_presc_100000 = avg_annual_total_quantity * 100000 / hb_population) %>% # average annual rate of prescriptions per 100,000
  select(hb_name, drug, avg_annual_presc_100000, hb_population) %>% # select columns of interest before pivot
  pivot_wider(names_from = drug, values_from = avg_annual_presc_100000, names_glue = "{drug}_rate") %>% # Rename columns for clarity
  clean_names() # clean column names following pivot

# calculate total ECP prescription rate per health board
ECP_anual_rate_data <- ECP_anual_rate_data %>% 
  mutate(total_ECP_rate = rowSums(select(., levonorgestrel_rate, ulipristal_acetate_rate), na.rm = TRUE)) %>%  #sum rates 
  arrange(desc(total_ECP_rate)) # arrange by total rate in descending order

#calculate percentage young people per health board to explore if there is an association here 
ECP_anual_rate_data_young <- ECP_anual_rate_data %>% 
  full_join(young_population_data) %>% # to get the population of those aged 16-34 years 
  group_by(hb_name) %>% 
  mutate(prop_young_ppl_hb = pop_hb_16_34/hb_population) %>% # calculate proportion of young people in each health board 
  ungroup()

Plot table 1:

annual_avg_ECP_table <- ECP_anual_rate_data_young %>% 
  select(hb_name, levonorgestrel_rate, ulipristal_acetate_rate, total_ECP_rate,prop_young_ppl_hb) %>% # Select relevant columns
  gt() %>% 
  cols_label(hb_name = "Health Board",
             total_ECP_rate= "Total",
             levonorgestrel_rate= " Levonorgestrel",
             ulipristal_acetate_rate=" Ulipristal Acetate",
             prop_young_ppl_hb = "% Aged 16-34 Years") %>% # rename columns to make reader-friendly
  fmt_number(columns = c(levonorgestrel_rate, ulipristal_acetate_rate, total_ECP_rate, prop_young_ppl_hb), decimals = 0) %>% # no decimal points as false accuracy detracts from the message in the data
  cols_align(align = "center", columns = c(levonorgestrel_rate,ulipristal_acetate_rate,total_ECP_rate, prop_young_ppl_hb)) %>%  # centre column names
  grand_summary_rows(columns = c(levonorgestrel_rate,ulipristal_acetate_rate, total_ECP_rate), fns = list("Overall Average" = ~mean(., na.rm = TRUE)), fmt = list(~ fmt_number(., decimals = 0))) %>% # add an overall average for the rate columns
  fmt_percent(columns = prop_young_ppl_hb, decimals = 0) %>%  # add percentage sign
  tab_header(title = md("**Average Annual Rate of Emergency Contraception Prescriptions by Health Board in Scotland.**"),
             subtitle = md("Rate per 100,000 women, derived from the mean prescription rates across the years 2019 to 2022. Health Boards are ranked in descending order.")) %>% # add a title and subtitle; md() allows text formatting from mark down 
  tab_spanner(label = md("*Prescription rate per 100,000 women*"), columns = c(levonorgestrel_rate,ulipristal_acetate_rate, total_ECP_rate)) %>% # add a title to the rate columns.
  tab_source_note(md("*Data from Public Health Scotland. Available from: (https://www.opendata.nhs.scot/dataset/prescriptions-in-the-community)*")) %>% 
  tab_stubhead(md("**2019-2022**")) %>% 
  tab_footnote(footnote = "includes Capital City, Edinburgh", locations = cells_body(columns = hb_name, rows = 2))%>% 
  opt_stylize(style = 6, color = "blue")

annual_avg_ECP_table
Average Annual Rate of Emergency Contraception Prescriptions by Health Board in Scotland.
Rate per 100,000 women, derived from the mean prescription rates across the years 2019 to 2022. Health Boards are ranked in descending order.
2019-2022 Health Board
Prescription rate per 100,000 women
% Aged 16-34 Years
Levonorgestrel Ulipristal Acetate Total
NHS Greater Glasgow and Clyde 3,376 29 3,404 26%
NHS Lothian1 2,495 56 2,551 27%
NHS Ayrshire and Arran 2,027 15 2,043 19%
NHS Tayside 1,365 22 1,387 22%
NHS Forth Valley 1,268 73 1,342 22%
NHS Grampian 1,210 16 1,226 22%
NHS Fife 1,049 54 1,103 22%
NHS Lanarkshire 784 48 832 22%
NHS Shetland 779 17 796 19%
NHS Orkney 609 7 616 17%
NHS Dumfries and Galloway 515 24 539 17%
NHS Western Isles 192 197 389 16%
NHS Highland 285 52 337 17%
NHS Borders 242 76 318 17%
Overall Average 1,157 49 1,206
Data from Public Health Scotland. Available from: (https://www.opendata.nhs.scot/dataset/prescriptions-in-the-community)
1 includes Capital City, Edinburgh

Table 1 presents the annual prescription rate of ECP per Health Board, alongside the proportion of young people living in each Health Board.

Key points to note:

  • NHS Greater Glasgow and Clyde and NHS Lothian have the highest annual ECP prescription rate. These regions encompass Scotland’s largest cities, Glasgow and Edinburgh, which may contribute to higher demand for ECP services.

  • Health boards with higher ECP prescription rates generally have a higher proportion of young people. This suggests that young people aged 16 to 34 years are more likely to require emergency contraception, in keeping with current literature (5).

  • NHS Ayrshire and Arran is an outlier. Despite having the third highest ECP prescription rate, it has a relatively smaller population of young people (19%). This warrants further exploration, as it may indicate greater use of ECP services by under 16s or over 35s in this region helping to guide targeted interventions.

  • Remote and rural Health Boards such as NHS Highland and NHS Borders had the lowest rate of ECP prescribing. They also had a smaller proportion of young people living in their health board, which may explain this observation.

  • Levonorgestrel is more commonly prescribed than Ulipristal Acetate across most Health Boards. However, in the NHS Western Isles Health Board the prescribing rates for Levonorgestrel and Ulipristal Acetate are nearly equal This variation may reflect disparities in prescribing practices between Health Boards. This is explored further in figure 3.

Are pharmacies in more deprived areas prescribing more ECP than those in affluent areas?

Read in and wrangle data:

# To measure deprivation I have used the Scottish Index of Multiple Deprivation. 2020v2 dataset from Public Health Scotland. (link available in code)
SIMD <- read_csv("https://www.opendata.nhs.scot/gl/dataset/78d41fa9-1a62-4f7b-9edb-3e8522a93378/resource/acade396-8430-4b34-895a-b3e757fa346e/download/simd2020v2_22062020.csv") %>%
  clean_names() %>%
  select(data_zone, simd2020v2hb_decile)

# I chose to use GP Practices and List Sizes from October 2022, as this was the closest dataset I could find which correlated with the final year of my prescriptions dataset:
gp_addresses <- read_csv("https://www.opendata.nhs.scot/dataset/f23655c3-6e23-4103-a511-a80d998adb90/resource/1a15cb34-fcf9-4d3f-ad63-1ba3e675fbe2/download/practice_contactdetails_oct2022-open-data.csv") %>%
  clean_names() %>%
  select(practice_code, gp_practice_name, data_zone)

# Create ECP_GP by using the GP_addresses dataset to map the GP practice code to a datazone. I then used the column datazone to full_join() the SIMD dataset to the prescriptions dataset.
ECP_GP <- ECP_scripts %>%
  filter(!gp_practice %in% c(99996, 99997, 99998)) %>% # remove dummy GP practice codes as they do not have a known gp practice code so cannot be mapped to a SIMD.
  left_join(gp_addresses, by = c("gp_practice" = "practice_code")) %>%
  #left_join(data_zones, by = "data_zone") %>%
  left_join(SIMD, by = "data_zone") %>%
  drop_na(simd2020v2hb_decile) %>% # need SIMD value to for plot
  group_by(gp_practice) %>% 
  mutate(total_quantity_per_gp = sum(paid_quantity)) %>% 
  clean_names()

# calculate the number of GPs per SIMD (account for each SIMD having a different number of GPs) 
toal_no_GP_per_SIMD <- ECP_GP %>% 
  group_by(simd2020v2hb_decile) %>%
  mutate(unique_gp_count_per_SIMD = n_distinct(gp_practice))

Plot figure 2:

ECP_SIMD_barchart <- toal_no_GP_per_SIMD %>%
  group_by(simd2020v2hb_decile, drug) %>% 
  summarise(prescriptions_gp = (total_quantity_per_gp / unique_gp_count_per_SIMD), # calculate the prescriptions per GP for each SIMD decile and drug
    .groups = "drop") %>%  # Ungroup data after summarisation
  ggplot(aes(x = factor(simd2020v2hb_decile, levels = 1:10),y = prescriptions_gp,  fill = drug, text = paste("Decile:", simd2020v2hb_decile, "<br>Drug:", drug))) + # customise hover box for interactive chart
  geom_col() +
  scale_fill_manual(values = c("#4575b4", "#91bfdb"), name = "Drug Type") +  # add colour palette
  labs(title = "Emergency Contraception Prescriptions by \n Scottish Index of Multiple Deprivation (SIMD) 2019 to 2022, \n normalised by number of GPs per SIMD decile.",
    x = "SIMD Decile \n (1 = Most Deprived, 10 = Least Deprived)",
    y = "Total Prescriptions",
    fill = "Drug") +
  theme_minimal(base_size = 12) +
  theme(plot.title = element_text(size = 14, face = "bold", hjust = 0.5),
    plot.subtitle = element_text(size = 12, hjust = 0.5),
    axis.title.x = element_text(size = 12),
    axis.title.y = element_text(size = 12),
    axis.text.x = element_text(size = 10, hjust = 1),
    axis.text.y = element_text(size = 10),
    legend.position = "right",
    legend.title = element_text(size = 12, face = "bold"),
    legend.text = element_text(size = 10))

ECP_SIMD_barchart <- ggplotly(ECP_SIMD_barchart, tooltip = "text") # make plot interactive
ECP_SIMD_barchart

Figure 2: Interactive Barchart showing Emergency Contraception Prescriptions by Scottish Index of Multiple Deprivation (SIMD).

Generally as SIMD decile increases the number of ECP prescriptions decreases. GPs in SIMD1, the most deprived areas, prescribe the most ECP, whilst increasing affluence is associated with a decline in ECP prescriptions. This suggests that individuals from more deprived areas utilise ECP services more frequently, highlighting a potential inequality in health needs.

This disparity may be due to factors such as education, awareness of safe sexual practices, environmental influences, or limited access to long-acting reversible contraception (LARC). Further investigation into these factors is essential to address this inequality.

Is there geographical variation in the prescribing practices of ECP by Health Board region?

This analysis explores if there was any correlation between the type of contraception prescribed and the location of the pharmacy. The ratio of total Levonorgestrel prescriptions to total emergency contraception prescriptions was calculated for each Health Board Region using the formula:

\[ \frac{Levonorgestrel}{Levonorgestrel + Ulipristal Acetate} = Ratio \]

A score close to 1 indicates that the majority of prescriptions in this region are for Levonorgestrel, whilst a score closer to 0 suggests that the majority of prescriptions are Ulipristal Acetate. This approach provides a useful way of identifying variation in prescribing practices.

Figure 3:

# load the NHS Health board Shapefile downloaded from learn page
NHS_healthboards <- st_read(here("data", "NHS_healthboards_2019.shp")) %>% 
  mutate(HBName = paste("NHS", HBName)) %>% # format to match ECP_scripts dataset
  clean_names()
## Reading layer `NHS_healthboards_2019' from data source 
##   `C:\Data_science\B273025\data\NHS_healthboards_2019.shp' using driver `ESRI Shapefile'
## Simple feature collection with 14 features and 4 fields
## Geometry type: MULTIPOLYGON
## Dimension:     XY
## Bounding box:  xmin: 7564.996 ymin: 530635.8 xmax: 468754.8 ymax: 1218625
## Projected CRS: OSGB36 / British National Grid
# calculate the ratio of Lev to Uli prescribed 
variation_ECP_prescribed <- ECP_scripts %>% 
  group_by(hb_name,drug) %>% 
  # calculate the total of Lev and Uli prescribed per health board
  summarise(total_each_drug_type = sum(paid_quantity, na.rm = TRUE)) %>%
  drop_na(drug) %>% 
  #pivot_wider to move drug names to columns 
  pivot_wider(names_from = drug, values_from = total_each_drug_type) %>%
  clean_names() %>% # consistency 
  mutate(levo_to_uli_ratio = levonorgestrel / (levonorgestrel + ulipristal_acetate)) # calculate ratio 

# Join spatial data with variation_ECP_prescribed
variation_ECP_prescribed <- NHS_healthboards %>%
  left_join(variation_ECP_prescribed)

#Create map in ggplot
map_variation_ECP_prescribed <- variation_ECP_prescribed %>%
  ggplot(aes(fill = levo_to_uli_ratio)) +
  geom_sf(size = 0.1, colour = "grey50", alpha =0.9) +
  scale_fill_distiller(palette = "Blues", direction = 1) +
  labs(title = "Geographical variation in Emergency Contraceptive \n Pill prescribing in Scotland.", 
       subtitle = "Heatmap showing Levonorgestrel prescriptions as a proportion of total \n Emergency Contraceptive Pill (ECP) prescriptions by Health Board region", 
       fill = "Levonorgestrel to ECP ratio", caption = "Data Source: Public Health Scotland Prescriptions in the Community, 2019-2022") +
  coord_sf() +
  theme_void() +
  theme(
    plot.title = element_text(face = "bold", size = 18, hjust=0.5), 
    plot.subtitle = element_text(size = 14, hjust=0.5), 
    legend.title = element_text(size = 12),
    legend.text = element_text(size = 9, hjust=0.5),
    legend.direction = "vertical",
    legend.box = "horizontal") +
  annotation_scale(location = "tl") +
  annotation_north_arrow(
    location = "tl",    
    pad_y = unit(0.5, "in"),    
    style = north_arrow_nautical(fill = c("grey40", "white"),line_col = "grey20"))

map_variation_ECP_prescribed
Figure 3: Heatmap exploring geographical variation in Emergency Contraception Pill prescribing

Figure 3: Heatmap exploring geographical variation in Emergency Contraception Pill prescribing

Health Board Regions in central Scotland predominantly prescribe Levonorgestrel, where as more remote and rural Health Board regions, such as the NHS Western Isles, prescribe higher proportions of Ulipristal Acetate. This difference in prescribing practices may reflect disparities in access to emergency contraception in remote and rural regions. Patients in these regions may present later to health services later, prompting prescribers to dispense Ulipristal Acetate due to its longer efficacy window. Alternatively, this variation could be attributed to differences in prescriber preferences or guidelines in more remote areas.

Conclusion

Prescriptions of emergency contraceptive pills (ECP) have decreased over the years 2019 to 2022. In 2020, there was a notable reduction in Levonorgestrel prescriptions, likely influenced by the Covid-19 lockdown. Ulipristal Acetate had a marked decline from 2019 onwards likely reflecting updated prescribing guidance, which discontinued its use in the treatment of uterine fibroids.

Health Board regions with larger populations of young people and major cities had higher rates of ECP prescriptions, whilst more remote regions with a smaller proportion of young people had a lower ECP prescription rate.

ECP prescriptions were more prevalent in areas of greater deprivation.

Geographically, remote pharmacies appeared to prescribe higher proportions of Ulipristal Acetate. This may be due to challenges in accessing pharmacies within 48 hours of unprotected sex, necessitating the use of Ulipristal Acetate, which has a longer efficacy window.

In conclusion, ECP prescribing patterns are influenced by multiple factors including societal events such as the Covid-19 pandemic, age, deprivation, and geography.

Recommendations from analysis

This report highlights significant disparities in the prescribing of emergency contraception across different geographic regions and levels of deprivation in Scotland. Further research is needed to understand the underlying causes of these trends, considering if there are barriers to access or differences in prescriber practices. These insights will be crucial for informing future sexual health policies and interventions aimed at reducing health inequalities and ensuring equitable access to emergency contraception.

Limitations of the dataset

  • This report assumes that Levonorgestrel and Ulipristal Acetate are dispensed exclusively for emergency contraception, wihtout considering potential off-licence uses.

  • Differences in the volume of ECP prescribed across Health Boards may result from patients living in one Health Board region but obtaining their ECP from a pharmacy in another Health Board region. This may result in inaccuracies in attributing prescription rates to specific Health Boards.

  • The prescription dataset included ‘dummy practice codes’ for prescriptions which lacked a specific practice code. This excluded a large number of ECP prescriptions from the ECP-deprivation analysis as it was impossible to link the prescriptions to a datazone and subsequent SIMD decile. This may impact the accuracy of the analysis.

Suggestions for future analysis

  • With additional time it would be interesting to design a Directed Acyclic Graphic to visually and mathematically model the probabilistic relationships between variables such as age, deprivation and geography on ECP prescribing patterns in Scotland.

  • It would be interesting to conduct statistical analysis to explore the trends in this report.

References

  1. Cleland K, Raymond EG, Westley E, Trussell J. Emergency contraception review: evidence-based recommendations for clinicians. Clin Obstet Gynecol [Internet]. 2014 Dec [cited 2024 Nov 25];57(4):741–50. Available from: https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4216625/
  2. Emergency Contraceptive Statistics 2023 | Click2Pharmacy [Internet]. 2023 [cited 2024 Nov 25]. Available from: https://click2pharmacy.co.uk/emergency-contraceptive-statistics-2023/
  3. Long Acting Reversible Methods of Contraception (LARC) in Scotland - Year ending 31 March 2022 - Long Acting Reversible Contraception (LARC) Key Clinical Indicator (KCI) - Publications - Public Health Scotland [Internet]. [cited 2024 Nov 25]. Available from: https://publichealthscotland.scot/publications/long-acting-reversible-contraception-larc-key-clinical-indicator-kci/long-acting-reversible-methods-of-contraception-larc-in-scotland-year-ending-31-march-2022/
  4. Ulipristal acetate 5mg medicinal products - referral | European Medicines Agency (EMA) [Internet]. 2020 [cited 2024 Nov 25]. Available from: https://www.ema.europa.eu/en/medicines/human/referrals/ulipristal-acetate-5mg-medicinal-products
  5. Mehta SD, Kulkarni AD, Pazol K, Koumans EH. Trends in Emergency Contraceptive Use Among Adolescents and Young Adults, 2006–2017. J Adolesc Health Off Publ Soc Adolesc Med [Internet]. 2022 Jul [cited 2024 Nov 25];71(1):86–93. Available from: https://www.ncbi.nlm.nih.gov/pmc/articles/PMC10982874/
LS0tDQp0aXRsZTogIkFzc2Vzc21lbnQ6IEV4cGxvcmF0b3J5IEFuYWx5c2lzIG9mIHRoZSBGYWN0b3JzIEluZmx1ZW5jaW5nIEVtZXJnZW5jeSBDb250cmFjZXB0aXZlIFByZXNjcmliaW5nIGluIFNjb3RsYW5kIg0KYXV0aG9yOiAiQjI3MzAyNSINCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCINCmxpbmstY2l0YXRpb25zOiB0cnVlDQpvdXRwdXQ6IA0KICBodG1sX2RvY3VtZW50Og0KICAgIGNvZGVfZG93bmxvYWQ6IHRydWUNCiAgICB0b2M6IHRydWUNCiAgICB0aGVtZTogZmxhdGx5DQoNCi0tLQ0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSwgbWVzc2FnZSA9IEZBTFNFLCB3YXJuaW5nID0gRkFMU0UsIGNhY2hlPUZBTFNFLCBmaWcuYWxpZ24gPSAiY2VudGVyIiwgZmlnLndpZHRoID0gMTAsIGZpZy5oZWlnaHQgPSA3KSAjIGFsaWduIGZpZ3VyZXMgdG8gY2VudHJlIGFuZCBzZXQgZGltZW5zaW9ucyB0byBwcmV2ZW50IHRoZW0gYmVpbmcgY3V0IG9mZiANCmBgYA0KDQojIEludHJvZHVjdGlvbiANCg0KUHJldmVudGluZyB1bmludGVuZGVkIHByZWduYW5jeSBpcyBjcml0aWNhbCBmb3IgaW5kaXZpZHVhbCB3ZWxsLWJlaW5nIGFuZCBwdWJsaWMgaGVhbHRoLiBVbnByb3RlY3RlZCBzZXggb2NjdXJzIGZvciBtdWx0aXBsZSwgY29tcGxleCByZWFzb25zIGluY2x1ZGluZyBzZXh1YWwgYXNzYXVsdCwgcmVwcm9kdWN0aXZlIGNvZXJjaW9uLCBjb250cmFjZXB0aXZlIG1pc2hhcHMsIGFuZCBsYXBzZXMgaW4gY29udHJhY2VwdGl2ZSB1c2UgKDEpLiBFbWVyZ2VuY3kgY29udHJhY2VwdGlvbiBwcmV2ZW50cyBwcmVnbmFuY3kgZm9sbG93aW5nIHVucHJvdGVjdGVkIHNleCBvciBjb250cmFjZXB0aXZlIGZhaWx1cmUuIEluIFNjb3RsYW5kIGVtZXJnZW5jeSBjb250cmFjZXB0aW9uIGlzIGF2YWlsYWJsZSBhcyBlaXRoZXIgYSBwaWxsIG9yIGludHJhdXRlcmluZSBkZXZpY2UuIE9yYWwgY29udHJhY2VwdGl2ZXMgYXJlIHRoZSBtb3N0IGNvbW1vbmx5IHVzZWQsIG1ha2luZyB1cCA5MCUgb2YgZW1lcmdlbmN5IGNvbnRyYWNlcHRpdmUgcHJlc2NyaXB0aW9ucyAoMikuIA0KDQpQaGFybWFjaWVzIGluIFNjb3RsYW5kIGRpc3BlbnNlIHR3byB0eXBlcyBvZiBlbWVyZ2VuY3kgY29udHJhY2VwdGl2ZSBwaWxscyAoRUNQKToNCg0KPiogKipMZXZvbm9yZ2VzdHJlbCAqKiAoYnJhbmQgbmFtZTogKkxldm9uZWxsZSopIC0gRWZmZWN0aXZlIHdpdGhpbiA3MiBob3VycyAodGhyZWUgZGF5cykgb2YgdW5wcm90ZWN0ZWQgc2V4DQo+KiAqKlVsaXByaXN0YWwgQWNldGF0ZSAqKiAoYnJhbmQgbmFtZTogKmVsbGFPbmUqKSAtIEVmZmVjdGl2ZSB3aXRoaW4gMTIwIGhvdXJzIChmaXZlIGRheXMpIG9mIHVucHJvdGVjdGVkIHNleCAgDQoNClRoaXMgYW5hbHlzaXMgZXhwbG9yZXMgdGhlIGZhY3RvcnMgaW5mbHVlbmNpbmcgcHJlc2NyaWJpbmcgdHJlbmRzIGZvciBFQ1AgaW4gU2NvdGxhbmQgZnJvbSAyMDE5IHRvIDIwMjIsIHVzaW5nIGRhdGEgZnJvbSB0aGUgUHVibGljIEhlYWx0aCBTY290bGFuZCBDb21tdW5pdHkgUHJlc2NyaXB0aW9ucyBEYXRhYmFzZS4gQnkgaW52ZXN0aWdhdGluZyBFQ1AgcGF0dGVybnMgb3ZlciB0aW1lLCBnZW9ncmFwaHkgYW5kIHNvY2lvZWNvbm9taWMgc3RhdHVzLCB0aGlzIHJlcG9ydCBhaW1zIHRvIGlkZW50aWZ5IGRpc3Bhcml0aWVzIGluIGFjY2VzcyBhbmQgaW5mb3JtIHN0cmF0ZWdpZXMgdG8gaW1wcm92ZSBwdWJsaWMgaGVhbHRoIG91dGNvbWVzLiANCg0KVGhlIGFuYWx5c2lzIGFkZHJlc3NlcyB0aGUgZm9sbG93aW5nIHF1ZXN0aW9uczogDQoNCj4gMSkgV2hhdCBhcmUgdGhlIHRyZW5kcyBpbiBwcmVzY3JpYmluZyBvZiBFQ1AgYmV0d2VlbiAyMDE5IGFuZCAyMDIyPyANCj4gMikgSG93IGRvZXMgdGhlIEVDUCBwcmVzY3JpcHRpb24gcmF0ZSB2YXJ5IGJ5IEhlYWx0aCBCb2FyZCByZWdpb25zIGluIFNjb3RsYW5kPw0KPiAzKSBBcmUgcGhhcm1hY2llcyBpbiBtb3JlIGRlcHJpdmVkIGFyZWFzIHByZXNjcmliaW5nIG1vcmUgRUNQIHRoYW4gdGhvc2UgaW4gYWZmbHVlbnQgYXJlYXM/DQo+IDQpIElzIHRoZXJlIGdlb2dyYXBoaWNhbCB2YXJpYXRpb24gaW4gcHJlc2NyaWJpbmcgcHJhY3RpY2VzIG9mIEVDUCBieSBIZWFsdGggQm9hcmQgcmVnaW9uPw0KDQpMb2FkIG5lY2Vzc2FyeSBsaWJyYXJpZXM6DQpgYGB7cn0NCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShqYW5pdG9yKSANCmxpYnJhcnkoZ3QpIA0KbGlicmFyeShoZXJlKQ0KbGlicmFyeShsdWJyaWRhdGUpDQpsaWJyYXJ5KHNmKQ0KbGlicmFyeShnZ3NwYXRpYWwpDQpsaWJyYXJ5KHBsb3RseSkNCmBgYA0KDQpSZWFkIGluIGRhdGFzZXRzOg0KYGBge3J9DQojIFJlYWQgaW4gdGhlIEhlYWx0aCBCb2FyZCBuYW1lcyAoSEJfbmFtZXMpLiBTZWUgY29kZSBmb3IgbGluay4NCkhCX25hbWVzIDwtIHJlYWRfY3N2KCJodHRwczovL3d3dy5vcGVuZGF0YS5uaHMuc2NvdC9kYXRhc2V0LzlmOTQyZmRiLWU1OWUtNDRmNS1iNTM0LWQ2ZTE3MjI5Y2M3Yi9yZXNvdXJjZS82NTJmZjcyNi1lNjc2LTRhMjAtYWJkYS00MzViOThkZDdiZGMvZG93bmxvYWQvaGIxNF9oYjE5LmNzdiIpICU+JSANCiAgY2xlYW5fbmFtZXMoKSAjIGVuc3VyZXMgY29sdW1uIG5hbWVzIGFyZSB1bmlxdWUsIGxvd2VyIGNhc2UgYW5kIHNwYWNlcyBhbmQgc3BlY2lhbCBjaGFyYWN0ZXJzIGFyZSByZXBsYWNlZCB3aXRoIHVuZGVyc2NvcmVzLiBJIHdpbGwgdXNlIHRoaXMgZnVuY3Rpb24gZm9yIGFsbCByZWFkIGlucyB0byBlbnN1cmUgbXkgZGF0YSBpcyBjb25zaXN0ZW50IGFuZCBlYXN5IHRvIG1hbmlwdWxhdGUuDQoNCiMgUmVhZCBpbiBwb3B1bGF0aW9uIGRhdGEgcGVyIEhlYWx0aCBCb2FyZCBmcm9tIHRoZSAyMDIyIGNlbnN1cyBkYXRhLiBBdmFpbGFibGUgZnJvbTogaHR0cHM6Ly9zdGF0aXN0aWNzLnVrZGF0YXNlcnZpY2UuYWMudWsvZGF0YXNldC9zY290bGFuZC1zLWNlbnN1cy0yMDIyLXV2MTAyYS1hZ2UtYnktc2V4L3Jlc291cmNlL2IyZDI5NWMyLWFmNTMtNGIzZC1hMDc1LTc4MTVjYWRkOTA2MCANCmFsbF9wb3B1bGF0aW9uX2RhdGEgPC0gcmVhZF9jc3YoaGVyZSgiZGF0YSIsICJVVjEwM19hZ2VfaGVhbHRoX2JvYXJkX2NlbnN1cy5jc3YiKSwgc2tpcCA9IDEwKSAlPiUgIyBsb2NhdGVzIHRoZSBjc3YgYW5kIGV4Y2x1ZGVzIHRoZSBmaXJzdCAxMCBsaW5lcyBpbiB0aGUgY3N2IGFzIHRoZXkgYXJlIHJlZHVuZGFudA0KICByZW5hbWUoU3BhcmUgPSAiLi4uNiIsICMgcmVtb3ZlIHVudXNlZCBjb2x1bW5zDQogICAgICAgICBoYl9uYW1lID0gIkhlYWx0aCBCb2FyZCBBcmVhIDIwMTkiLA0KICAgICAgICAgaGJfcG9wdWxhdGlvbiA9IENvdW50KSAlPiUgIyByZW5hbWUoKSBmb3JtYXRzIHRoZSBkYXRhIHRvIG1hdGNoIHRoZSBwcmVzY3JpcHRpb25zIGRhdGFmcmFtZQ0KICBmaWx0ZXIoU2V4ID09ICJGZW1hbGUiKSAlPiUgIyBmaWx0ZXIgZmVtYWxlIHBvcHVsYXRpb24sIGFzIG1lbiBkbyBub3QgdGFrZSBFQ1ANCiAgc2VsZWN0KGhiX25hbWUsIEFnZSwgaGJfcG9wdWxhdGlvbikgJT4lICMgc2VsZWN0IGNvbHVtbnMgb2YgaW50ZXJlc3QNCiAgbXV0YXRlKGhiX25hbWUgPSBwYXN0ZSgiTkhTIiwgaGJfbmFtZSkpICU+JSAgIyBjaGFuZ2UgaGJfbmFtZSBjb2x1bW4gZm9ybWF0IHRvIG1hdGNoIHRoZSBIZWFsdGggQm9hcmQgZGF0YWZyYW1lIGZvcm1hdA0KICBjbGVhbl9uYW1lcygpDQoNCiMgZmlsdGVyIGRhdGFzZXQgZm9yIHRoZSB0b3RhbCBmZW1hbGUgcG9wdWxhdGlvbiBmb3IgZWFjaCBoZWFsdGggYm9hcmQ6DQpwb3B1bGF0aW9uX2RhdGEgPC0gYWxsX3BvcHVsYXRpb25fZGF0YSAlPiUgDQogIGZpbHRlcihhZ2UgPT0gIkFsbCBwZW9wbGUiKSAlPiUgDQogIHNlbGVjdChoYl9uYW1lLCBoYl9wb3B1bGF0aW9uKQ0KDQojIHNlbGVjdCB0aGUgcG9wdWxhdGlvbiBhZ2VkIDE2IHRvIDM0IHllYXJzIGFzIHRoaXMgaXMgdGhlIHBvcHVsYXRpb24gdGhlIHBvcHVsYXRpb24gbW9zdCBsaWtlbHkgZW5nYWdpbmcgd2l0aCByaXNrIHRha2luZyBiZWhhdmlvcnMgc3VjaCBhcyB1bnByb3RlY3RlZCBzZXguIEkgY2hvc2UgMTYgYXMgdGhpcyBpcyB0aGUgYWdlIG9mIGNvbnNlbnQgaW4gU2NvdGxhbmQsIGFuZCAzNCBhcyBteSBjdXQgb2ZmIGZvciB5b3VuZyBhZHVsdHMuIA0KeW91bmdfcG9wdWxhdGlvbl9kYXRhIDwtIGFsbF9wb3B1bGF0aW9uX2RhdGEgJT4lIA0KICBmaWx0ZXIoYWdlJWluJSBjKDE2OjM0KSkgJT4lICMgZmlsdGVyIGFnZXMgb2YgaW50ZXJlc3QNCiAgbXV0YXRlKGFnZSA9IGFzLm51bWVyaWMoYWdlKSkgJT4lICMgbWFrZSBudW1lcmljYWwgc28gdGhleSBjYW4gYmUgcGxhY2VkIGluIHRvIGJ1Y2tldHMNCiAgbXV0YXRlKGFnZV9ncm91cCA9IGNhc2Vfd2hlbihiZXR3ZWVuKGFnZSwgMTYsMzQpficxNi0zNCcpKSAlPiUgIyBtYWtlIGJ1Y2tldCAxNi0zNCB5ZWFycw0KICBncm91cF9ieShoYl9uYW1lLCBhZ2VfZ3JvdXApICU+JSANCiAgc3VtbWFyaXNlKHBvcF9oYl8xNl8zNCA9IHN1bShoYl9wb3B1bGF0aW9uKSkgIyBzdW0gdG90YWwgcG9wdWxhdGlvbiBhZ2VkIDE2IHRvIDM0IHBlciBoZWFsdGggYm9hcmQgcmVnaW9uLiANCg0KYGBgDQoNCioqRGVmaW5lIGEgZnVuY3Rpb24qKiB0byByZWFkIGluIHRoZSBwcmVzY3JpcHRpb24gZGF0YSBmb3IgYSBkZWZpbmVkIHllYXI6DQpgYGB7cn0NCiNGb3IgZWZmaWNpZW5jeSBJIGNyZWF0ZWQgYSBmdW5jdGlvbiB0byByZWFkIGluIHRoZSBwcmVzY3JpcHRpb25zIGRhdGFzZXRzLiBJIGRvd25sb2FkZWQgMTIgbW9udGhzIG9mIHByZXNjcmlwdGlvbiBkYXRhIGZvciBlYWNoIHllYXIgZnJvbSAyMDE5IHRvIDIwMjIuIEkgcGxhY2VkIHRoZSAxMiBtb250aHMgb2YgZGF0YSBpbnRvIHRoZWlyIHJlbGV2YW50IGZvbGRlciBuYW1lZCBhbGxfbW9udGhzX3llYXIsIHdoZXJlIHllYXIgd2FzIHNwZWNpZmljIHRvIHRoZSBkYXRhIGl0IGNvbnRhaW5lZC4NCnJlYWRfYWxsX3ByZXNjcmlwdGlvbnMgPC0gZnVuY3Rpb24oeWVhcil7DQogIGFsbF9maWxlcyA8LSBsaXN0LmZpbGVzKGhlcmUoImRhdGEiLCBwYXN0ZTAoImFsbF9tb250aHNfIiwgeWVhcikpLCBwYXR0ZXJuID0gImNzdiIpICNsaXN0LmZpbGVzKCkgcmV0cmlldmVzIGZpbGVzIGZyb20gdGhlIHJlbGV2YW50IGRpcmVjdG9yeSwgYW5kIHRoZSBwYXN0ZTAoKSBkeW5hbWljYWxseSBjb25zdHJ1Y3RzIHRoZSBmb2xkZXIgbmFtZSBiYXNlZCBvbiB0aGUgeWVhciB2YXJpYWJsZSBwbGFjZWQgaW50byB0aGUgZnVuY3Rpb24uDQogIGFsbF9wcmVzY3JpcHRpb25zIDwtIGFsbF9maWxlcyAlPiUNCiAgICBtYXBfZGZyKH5yZWFkX2NzdihoZXJlKCJkYXRhIiwgcGFzdGUwKCJhbGxfbW9udGhzXyIsIHllYXIpLC4pKSkgJT4lICNtYXBfZGZyKCkgcm93LWJpbmRzIHRoZSBkYXRhc2V0cyBiZWluZyByZWFkIGluDQogICAgY2xlYW5fbmFtZXMoKSAlPiUNCiAgICBkcm9wX25hKGJuZl9pdGVtX2Rlc2NyaXB0aW9uKSAjIGRyb3AgdGhlIHJvd3Mgd2l0aCBtaXNzaW5nIGJuZl9pdGVtIHZhbHVlcw0KICByZXR1cm4oYWxsX3ByZXNjcmlwdGlvbnMpfQ0KYGBgDQoNClJlYWQgaW4gZGF0YXNldHMgdXNpbmcgKipyZWFkX2FsbF9wcmVzY3JpcHRpb25zKCkqKiBmdW5jdGlvbiBhbmQgc3RhcnQgZGF0YSB3cmFuZ2xpbmc6DQpgYGB7cn0NCiMgYWxsX3ByZXNjcmlwdGlvbnNfMjAxOSA8LSByZWFkX2FsbF9wcmVzY3JpcHRpb25zKDIwMTkpDQojIGFsbF9wcmVzY3JpcHRpb25zXzIwMjAgPC0gcmVhZF9hbGxfcHJlc2NyaXB0aW9ucygyMDIwKQ0KIyBhbGxfcHJlc2NyaXB0aW9uc18yMDIxIDwtIHJlYWRfYWxsX3ByZXNjcmlwdGlvbnMoMjAyMSkNCiMgYWxsX3ByZXNjcmlwdGlvbnNfMjAyMiA8LSByZWFkX2FsbF9wcmVzY3JpcHRpb25zKDIwMjIpDQojIA0KIyAjIDIwMTkgZGF0YXNldCBoYXMgaGJ0MjAxNCBhcyBhIGNvbHVtbiBuYW1lIGluc3RlYWQgb2YgaGJ0LiBSZW5hbWUgdG8gbWFrZSBjb2x1bW4gbmFtZSBjb25zaXN0ZW50DQojIGFsbF9wcmVzY3JpcHRpb25zXzIwMTkgPC0gYWxsX3ByZXNjcmlwdGlvbnNfMjAxOSAlPiUNCiMgICByZW5hbWUoaGJ0ID0gImhidDIwMTQiKQ0KIyANCiMgIyBjb21iaW5lIDQgeWVhcnMgb2YgZGF0YSBpbnRvIG9uZSBkYXRhc2V0IHRvIG1ha2UgaXQgZWFzaWVyIHRvIHdyYW5nbGUNCiMgY29tYmluZWRfcHJlc2NyaXB0aW9ucyA8LSBiaW5kX3Jvd3MoDQojICAgYWxsX3ByZXNjcmlwdGlvbnNfMjAxOSwNCiMgICBhbGxfcHJlc2NyaXB0aW9uc18yMDIwLA0KIyAgIGFsbF9wcmVzY3JpcHRpb25zXzIwMjEsDQojICAgYWxsX3ByZXNjcmlwdGlvbnNfMjAyMiApJT4lICMgSSBtdXRhdGUgYW5kIHNlbGVjdCB0aGUgcHJlc2NyaXB0aW9ucyBvZiBpbnRlcmVzdCB0byBwcmV2ZW50IGEgdmVyeSBsYXJnZSBkYXRhc2V0IGZyb20gYmVpbmcgc3RvcmVkIGluIG15IGVudmlyb25tZW50IChwcmV2ZW50cyBSIHNsb3dpbmcgZG93biBhbmQgY3Jhc2hpbmcpDQojICAgbXV0YXRlKA0KIyAgICAgZGF0ZSA9IHBhcnNlX2RhdGVfdGltZShwYWlkX2RhdGVfbW9udGgsICJ5bSIpLCAjIHVzZSBsdWJyaWRhdGUgdG8gZm9ybWF0IGRhdGUNCiMgICAgIGRydWdfc2ltcGxlID0gY2FzZV93aGVuKA0KIyAgICAgICBzdHJfZGV0ZWN0KGJuZl9pdGVtX2Rlc2NyaXB0aW9uLCAiTEVWT05PIikgfiAiTGV2b25vcmdlc3RyZWwiLA0KIyAgICAgICBzdHJfZGV0ZWN0KGJuZl9pdGVtX2Rlc2NyaXB0aW9uLCAiVUxJUFIiKSB+ICJVbGlwcmlzdGFsIEFjZXRhdGUiLA0KIyAgICAgICBUUlVFIH4gIk90aGVyIikpICU+JSAjIHVzZWQgY2FzZV93aGVuKCkgdG8gc2VsZWN0IEVDUCBldmVuIHdoZW4gdGhleSBoYXZlIGRpZmZlcmVudCBkb3NhZ2VzDQojICAgZmlsdGVyKGRydWdfc2ltcGxlICE9ICJPdGhlciIsIWlzLm5hKGRhdGUpKSAlPiUgI3JlbW92ZSBwcmVzY3JpcHRpb25zIG9mIG5vIGludGVyZXN0IGFuZCBhbnkgbWlzc2luZyBkYXRlIHZhbHVlcw0KIyAgIGZpbHRlcihoYnQgIT0gIlNCMDgwNiIpICU+JSAjIGZpbHRlciBvdXQgU0IwODA2IGFzIGl0IGlzIG5vdCBhIGhlYWx0aCBib2FyZCAoU2NvdHRpc2ggQW1idWxhbmNlIFNlcnZpY2UpDQojICAgZmlsdGVyKCFpcy5uYShoYnQpKQ0KDQojIHNhdmUgY29tYmluZWRfcHJlc2NyaXB0aW9ucyBkYXRhc2V0IHRvIGEgY3N2IGluIG15IGRpcmVjdG9yeSwgdG8gcHJldmVudCBtYW55IGxhcmdlIGRhdGFzZXRzIGJlaW5nIHN0b3JlZCBpbiBteSBlbnZpcm9ubWVudCBhbmQgc2xvd2luZyBkb3duIFIuIA0KIyB3cml0ZV9jc3YoY29tYmluZWRfcHJlc2NyaXB0aW9ucywiZGF0YS9jb21iaW5lZF9wcmVzY3JpcHRpb25zLmNzdiIpDQpjb21iaW5lZF9wcmVzY3JpcHRpb25zIDwtIHJlYWRfY3N2KGhlcmUoImRhdGEiLCJjb21iaW5lZF9wcmVzY3JpcHRpb25zLmNzdiIpKQ0KYGBgDQoNCkpvaW4gYW5kIHdyYW5nbGUgZGF0YSBuYW1pbmcgdGhlIG91dHB1dCB2YXJpYWJsZSAqKkVDUF9zY3JpcHRzKio6DQpgYGB7cn0NCiMgam9pbiB0aGUgcHJlc2NyaXB0aW9ucyBkYXRhc2V0IHRvIHRoZSBIZWFsdGggQm9hcmQgbmFtZXMgYW5kIGhlYWx0aCBib2FyZCBwb3B1bGF0aW9uIGRhdGFzZXRzDQpFQ1Bfc2NyaXB0cyA8LSBjb21iaW5lZF9wcmVzY3JpcHRpb25zICU+JSANCiAgZnVsbF9qb2luKEhCX25hbWVzLCBieSA9IGMoImhidCIgPSAiaGIiKSkgJT4lICMgam9pbiB3aXRoIEhlYWx0aCBCb2FyZCBuYW1lcw0KICBmdWxsX2pvaW4ocG9wdWxhdGlvbl9kYXRhLCBieSA9ICJoYl9uYW1lIikgJT4lICMgam9pbiB3aXRoIHBvcHVsYXRpb24gZGF0YQ0KICBzZWxlY3QoZ3BfcHJhY3RpY2UsIGRhdGUsIGRydWcgPSBkcnVnX3NpbXBsZSwgaGJfbmFtZSwgcGFpZF9xdWFudGl0eSxoYl9wb3B1bGF0aW9uKSAlPiUgICMgc2VsZWN0IGNvbHVtbnMgb2YgaW50ZXJlc3QNCiAgbXV0YXRlKG1vbnRoID0gZmFjdG9yKG1vbnRoKGRhdGUpLCBsZXZlbHMgPSAxOjEyLCBsYWJlbHMgPSBtb250aC5hYmIpLCAuYWZ0ZXIgPSBkYXRlKSAlPiUgICANCiAgbXV0YXRlKHllYXIgPSBmYWN0b3IoeWVhcihkYXRlKSksIC5hZnRlciA9IG1vbnRoKSAjIGV4dHJhY3QgbW9udGggYW5kIHllYXIgYXMgYSBmYWN0b3Igd2l0aCBsYWJlbHMgdG8gaGVscCB3aGVuIHBsb3R0aW5nDQpgYGANCg0KIyBLZXkgUmVzdWx0cyANCg0KIyMgV2hhdCBhcmUgdGhlIHRyZW5kcyBpbiBwcmVzY3JpYmluZyBvZiBFQ1AgYmV0d2VlbiAyMDE5IGFuZCAyMDIyPyANCg0KYGBge3IgdGltZV90cmVuZCwgZmlnLmNhcD0gIkZpZ3VyZSAxOiBQcmVzY3JpYmluZyB0cmVuZHMgb2YgRW1lcmdlbmN5IENvbnRyYWNlcHRpb24gZnJvbSAyMDE5IHRvIDIwMjIifQ0KDQojIGNhbGN1bGF0ZSB0b3RhbCBwb3B1bGF0aW9uIG9mIFNjb3RsYW5kDQp0b3RhbF9mZW1hbGVfcG9wdWxhdGlvbiA8LSBzdW0ocG9wdWxhdGlvbl9kYXRhJGhiX3BvcHVsYXRpb24sIG5hLnJtPVRSVUUpIA0KDQojIGNhbGN1bGF0ZSB0aGUgbnVtYmVyIG9mIHByZXNjcmlwdGlvbnMgb2YgZWFjaCBkcnVnIHBlciBtb250aA0KRUNQX2J5X21vbnRoIDwtIEVDUF9zY3JpcHRzICU+JQ0KICBncm91cF9ieShkYXRlLCBkcnVnLCBtb250aCwgeWVhcikgJT4lDQogIHN1bW1hcmlzZSh0b3RhbF9xdWFudGl0eV9tb250aCA9IHN1bShwYWlkX3F1YW50aXR5LCBuYS5ybSA9IFRSVUUpKSAlPiUNCiAgdW5ncm91cCgpICU+JSANCiAgZHJvcF9uYShkcnVnKSAlPiUgDQogIGNsZWFuX25hbWVzKCkNCg0KIyBjYWxjdWxhdGUgcHJlc2NyaXB0aW9uIHJhdGUgcGVyIDEwMCwwMDAgcGVvcGxlIGZvciBlYWNoIGRydWcgYW5kIG1vbnRoDQpFQ1BfdHJlbmRfcGxvdF9kYXRhIDwtIEVDUF9ieV9tb250aCAlPiUNCiAgZ3JvdXBfYnkoZHJ1ZywgeWVhciwgbW9udGgpICU+JSANCiAgc3VtbWFyaXNlKHByZXNjcmlwdGlvbnNfcGVyXzEwMDAwMCA9ICh0b3RhbF9xdWFudGl0eV9tb250aCAvIHRvdGFsX2ZlbWFsZV9wb3B1bGF0aW9uKSoxMDAwMDApDQoNCkVDUF90cmVuZF9wbG90IDwtIEVDUF90cmVuZF9wbG90X2RhdGEgJT4lDQogIGdncGxvdChhZXMoeCA9IG1vbnRoLCB5ID0gcHJlc2NyaXB0aW9uc19wZXJfMTAwMDAwLCBncm91cCA9IHllYXIsIGxpbmV0eXBlID0geWVhciwgY29sb3IgPSB5ZWFyKSkgKyAjIHBsb3QgZGF0YSBmb3IgZWFjaCB5ZWFyIG9uIHNhbWUgZ3JhcGgNCiAgZ2VvbV9saW5lKGFlcyhzaXplID0gaWZlbHNlKHllYXIgPT0gIjIwMjAiLCAwLjksIDAuNykpKSArICMgbWFrZSB0aGUgMjAyMCBsaW5lIHNsaWdodGx5IHRoaWNrZXIgdG8gbWFrZSBpdCBzdGFuZCBvdXQgDQogIGZhY2V0X3dyYXAofmRydWcsIHNjYWxlcyA9ICJmcmVlX3kiKSArICMgc2VwYXJhdGUgdGhlIHR3byB0eXBlcyBvZiBFQ1ANCiAgc2NhbGVfbGluZXR5cGVfbWFudWFsKHZhbHVlcyA9IGMoIjIwMTkiID0gImRvdGRhc2giLCAiMjAyMCIgPSAic29saWQiLCAiMjAyMSIgPSAiZGFzaGVkIiwgIjIwMjIiID0gImRvdHRlZCIpLG5hbWUgPSAiWWVhciIpICsgIyBtYWtlIGVhY2ggeWVhciBpZGVudGlmaWFibGUgYnkgbGludGUgdHlwZQ0KICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygiMjAxOSIgPSAiZ3JleTcwIiwgIjIwMjAiID0gIiM0NTc1YjQiLCAiMjAyMSIgPSAiZ3JleTcwIiwgIjIwMjIiID0gImdyZXk3MCIpLG5hbWUgPSAiWWVhciIpICsgIyBtYWtlIENvdmlkLTE5IHllYXIgYmx1ZSAoMjAyMCBoYWQgdGhlIGxvbmdlc3QgbG9ja2Rvd24sIE1hcmNoIHRpbGwgTWF5KQ0KICBzY2FsZV9zaXplX2lkZW50aXR5KCkgKyAjIGVuc3VyZXMgZ2dwbG90IHVzZXMgdGhlIHNpemUgdmFsdWVzIGFzIG91dGxpbmVkIGluIGdlb21fbGluZSgpDQogIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKDAsIE5BKSwgYnJlYWtzID0gc2NhbGVzOjpwcmV0dHlfYnJlYWtzKG4gPSA1KSkrICMgZW5zdXJlIHktYXhpcyBzdGFydHMgYXQgMCBhbmQgaGFzIGV2ZW5seSBzcGFjZWQgYnJlYWtzIA0KICBsYWJzKA0KICAgIHRpdGxlID0gIlRyZW5kcyBpbiBFbWVyZ2VuY3kgQ29udHJhY2VwdGlvbiBQcmVzY3JpYmluZyAyMDE54oCTMjAyMiBcbiBpbiBTY290bGFuZC4iLA0KICAgIHN1YnRpdGxlID0gIkZvdXIgeWVhcnMgb2YgcG9wdWxhdGlvbiBhZGp1c3RlZCBwcmVzY3JpYmluZyByYXRlc1xuICBoaWdobGlnaHRpbmcgdGhlIGltcGFjdCBvZiBDb3ZpZC0xOSAoYmx1ZSkiLA0KICAgIHggPSAiTW9udGgiLA0KICAgIHkgPSAiUHJlc2NyaXB0aW9ucyBwZXIgMTAwLDAwMCB3b21lbiIpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUoDQogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTgsIGhqdXN0ID0gMC41LCBmYWNlID0gImJvbGQiKSwNCiAgICBwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCwgaGp1c3QgPSAwLjUpLA0KICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLA0KICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLA0KICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSwgc2l6ZSA9IDkpLA0KICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSA5KSwNCiAgICBzdHJpcC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksDQogICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksDQogICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwNCiAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIiwNCiAgICBwbG90Lm1hcmdpbiA9IG1hcmdpbigxMCwgMzAsIDEwLCAzMCkpICMgaW5jcmVhc2Ugc2l6ZSBvZiBtYXJnaW5zDQoNCkVDUF90cmVuZF9wbG90DQpgYGANCg0KRmlndXJlIDEgZXhwbG9yZXMgdGhlIG1vbnRobHkgdmFyaWF0aW9uIGluIHByZXNjcmliaW5nIHJhdGUgb2YgRUNQIGZyb20gMjAxOSB0byAyMDIyLiA0IGNvbnNlY3V0aXZlIHllYXJzIG9mIGRhdGEgd2VyZSBhbmFseXNlZCB0byBpbnZlc3RpZ2F0ZSB3aGV0aGVyIHNwZWNpZmljIGV2ZW50cywgc3VjaCBhcyB0aGUgQ292aWQtMTkgcGFuZGVtaWMgb3IgdGhlIENvbW1vbiBXZWFsdGggR2FtZXMgaW5mbHVlbmNlZCBFQ1AgcHJlc2NyaWJpbmcgcmF0ZXMuIA0KDQpJbnRlcmVzdGluZyB0cmVuZHMgdG8gbm90ZSBpbmNsdWRlOg0KDQoqICoqTGV2b25vcmdlc3RyZWwgaXMgbW9yZSBjb21tb25seSBwcmVzY3JpYmVkIHRoYW4gVWxpcHJpc3RhbCBBY2V0YXRlLioqIEVhY2ggbW9udGggYW4gYXZlcmFnZSBvZiAxNTAgcHJlc2NyaXB0aW9ucyBvZiBMZXZvbm9yZ2VzdHJlbCBhbmQgMyBwcmVzY3JpcHRpb25zIG9mIFVsaXByaXN0YWwgQWNldGF0ZSBhcmUgZGlzcGVuc2VkIHBlciAxMDAsMDAwIHdvbWVuIGFjcm9zcyBTY290bGFuZC4gDQoNCiogKipUaGUgcHJlc2NyaWJpbmcgcmF0ZSBvZiBMZXZvbm9yZ2VzdHJlbCBoYXMgZGVjcmVhc2VkIGFubnVhbGx5IGJldHdlZW4gMjAxOSBhbmQgMjAyMi4qKiBUaGlzIHRyZW5kIG1heSByZWZsZWN0IHB1YmxpYyBoZWFsdGggZWZmb3J0cyB0byBwcm9tb3RlIGxvbmctYWN0aW5nIHJldmVyc2libGUgY29udHJhY2VwdGlvbiAoTEFSQyksIHRoZXJlYnkgcmVkdWNpbmcgdGhlIG5lZWQgZm9yIEVDUCAoMykuIEFsdGVybmF0aXZlbHkgaXQgY291bGQgcmVzdWx0IGZyb20gY2hhbGxlbmdlcyBpbiBhY2Nlc3NpbmcgRUNQIGR1cmluZyB0aGUgQ292aWQtMTkgcGFuZGVtaWMuIA0KDQoqICoqQSBzaWduaWZpY2FudCByZWR1Y3Rpb24gaW4gVWxpcHJpc3RhbCBBY2V0YXRlIHByZXNjcmlwdGlvbnMgaXMgb2JzZXJ2ZWQgZnJvbSAyMDIwIG9ud2FyZHMuKiogRHVlIHRvIGxvdyBwcmVzY3JpYmluZyByYXRlcyBvZiBVbGlwcmlzdGFsIEFjZXRhdGUgdGhlcmUgaXMgc29tZSBzdG9jaGFzdGljIHZhcmlhdGlvbiBob3dldmVyIHRoZSBkb3dud2FyZCB0cmVuZCBpbiAyMDIwIGlzIGNsZWFyLiBUaGlzIGxpa2VseSBjb3JyZXNwb25kcyB0byB0aGUgRXVyb3BlYW4gTWVkaWNpbmVzIEFnZW5jeSdzIDIwMjAgZ3VpZGFuY2UgcmVjb21tZW5kaW5nIHRoZSB3aXRoZHJhd2FsIG9mIFVsaXByaXN0YWwgQWNldGF0ZSBmb3IgdGhlIHRyZWF0bWVudCBmb3IgdXRlcmluZSBmaWJyb2lkcyBkdWUgdG8gc2FmZXR5IGNvbmNlcm5zLiBGcm9tIDIwMjAsIHByZXNjcmlwdGlvbnMgb2YgVWxpcHJpc3RhbCBBY2V0YXRlIGFwcGVhciBzcGVjaWZpYyB0byBFQ1AgdXNlIG9ubHkgKDQpLiAgDQoNCiogU2Vhc29uYWwgcGVha3MgYXJlIG9ic2VydmVkIGluIHRoZSBzdW1tZXIgbW9udGhzIG9mIGFsbCB5ZWFycy4gVGhpcyBzdWdnZXN0cyBhbiBpbmNyZWFzZWQgZGVtYW5kIGZvciBFQ1AgZHVyaW5nIHdoYXQgY291bGQgYmUgZGVzY3JpYmVkIGFzIGEgKionU3VtbWVyIG9mIExvdmUnKiouDQoNCiogKipBIG1hcmtlZCBkZWNsaW5lIGluIExldm9ub3JnZXN0cmVsIHByZXNjcmlwdGlvbnMgb2N1cnJlZCBiZXR3ZWVuIEZlYnJ1YXJ5IGFuZCBNYXkgb2YgMjAyMC4qKiBUaGlzIGNvaW5jaWRlcyB3aXRoIHRoZSBQaGFzZSAxIENvdmlkLTE5IGxvY2tkb3duLCBzdWdnZXN0aW5nIHRoYXQgbmF0aW9uYWwgbG9ja2Rvd24gbWF5IGhhdmUgcmVkdWNlZCBvcHBvcnR1bml0aWVzIGZvciB1bnByb3RlY3RlZCBzZXh1YWwgaW50ZXJjb3Vyc2UuIA0KDQojIyBIb3cgZG9lcyB0aGUgRUNQIHByZXNjcmlwdGlvbiByYXRlIHZhcnkgYnkgSGVhbHRoIEJvYXJkIHJlZ2lvbnMgaW4gU2NvdGxhbmQ/IA0KDQpXcmFuZ2xlIGRhdGEgdG8gZ2V0IHRoZSBjb2x1bW5zIGFuZCB2YWx1ZXMgb2YgaW50ZXJlc3Q6IA0KYGBge3J9DQpFQ1BfYW51YWxfcmF0ZV9kYXRhIDwtIEVDUF9zY3JpcHRzICU+JSANCiAgZ3JvdXBfYnkoaGJfbmFtZSwgZHJ1ZykgJT4lICMgYWdncmVnYXRlIGRhdGEgYnkgSGVhbHRoIEJvYXJkIGFuZCBkcnVnDQogIHN1bW1hcmlzZSh0b3RhbF9xdWFudGl0eV80X3llYXJzID0gc3VtKHBhaWRfcXVhbnRpdHksIG5hLnJtID0gVFJVRSksICMgdG90YWwgcHJlc2NyaXB0aW9ucyBvdmVyIDQgeWVhcnMNCiAgICBhdmdfYW5udWFsX3RvdGFsX3F1YW50aXR5ID0gdG90YWxfcXVhbnRpdHlfNF95ZWFycyAvIDQsICMgYXZlcmFnZSBhbm51YWwgcHJlc2NyaXB0aW9ucw0KICAgIGhiX3BvcHVsYXRpb24gPSBmaXJzdChoYl9wb3B1bGF0aW9uKSwgIyBoYl9wb3B1bGF0aW9uIGlzIGNvbnNpc3RlbnQgd2l0aGluIGVhY2ggaGJfbmFtZQ0KICAgIC5ncm91cHMgPSAiZHJvcCIpICU+JSAjIHVuZ3JvdXAgZGF0YQ0KICBkcm9wX25hKGRydWcpICU+JSAjIHJlbW92ZSByb3dzIHdpdGggbm8gZHJ1ZyB2YWx1ZXMNCiAgbXV0YXRlKGF2Z19hbm51YWxfcHJlc2NfMTAwMDAwID0gYXZnX2FubnVhbF90b3RhbF9xdWFudGl0eSAqIDEwMDAwMCAvIGhiX3BvcHVsYXRpb24pICU+JSAjIGF2ZXJhZ2UgYW5udWFsIHJhdGUgb2YgcHJlc2NyaXB0aW9ucyBwZXIgMTAwLDAwMA0KICBzZWxlY3QoaGJfbmFtZSwgZHJ1ZywgYXZnX2FubnVhbF9wcmVzY18xMDAwMDAsIGhiX3BvcHVsYXRpb24pICU+JSAjIHNlbGVjdCBjb2x1bW5zIG9mIGludGVyZXN0IGJlZm9yZSBwaXZvdA0KICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gZHJ1ZywgdmFsdWVzX2Zyb20gPSBhdmdfYW5udWFsX3ByZXNjXzEwMDAwMCwgbmFtZXNfZ2x1ZSA9ICJ7ZHJ1Z31fcmF0ZSIpICU+JSAjIFJlbmFtZSBjb2x1bW5zIGZvciBjbGFyaXR5DQogIGNsZWFuX25hbWVzKCkgIyBjbGVhbiBjb2x1bW4gbmFtZXMgZm9sbG93aW5nIHBpdm90DQoNCiMgY2FsY3VsYXRlIHRvdGFsIEVDUCBwcmVzY3JpcHRpb24gcmF0ZSBwZXIgaGVhbHRoIGJvYXJkDQpFQ1BfYW51YWxfcmF0ZV9kYXRhIDwtIEVDUF9hbnVhbF9yYXRlX2RhdGEgJT4lIA0KICBtdXRhdGUodG90YWxfRUNQX3JhdGUgPSByb3dTdW1zKHNlbGVjdCguLCBsZXZvbm9yZ2VzdHJlbF9yYXRlLCB1bGlwcmlzdGFsX2FjZXRhdGVfcmF0ZSksIG5hLnJtID0gVFJVRSkpICU+JSAgI3N1bSByYXRlcyANCiAgYXJyYW5nZShkZXNjKHRvdGFsX0VDUF9yYXRlKSkgIyBhcnJhbmdlIGJ5IHRvdGFsIHJhdGUgaW4gZGVzY2VuZGluZyBvcmRlcg0KDQojY2FsY3VsYXRlIHBlcmNlbnRhZ2UgeW91bmcgcGVvcGxlIHBlciBoZWFsdGggYm9hcmQgdG8gZXhwbG9yZSBpZiB0aGVyZSBpcyBhbiBhc3NvY2lhdGlvbiBoZXJlIA0KRUNQX2FudWFsX3JhdGVfZGF0YV95b3VuZyA8LSBFQ1BfYW51YWxfcmF0ZV9kYXRhICU+JSANCiAgZnVsbF9qb2luKHlvdW5nX3BvcHVsYXRpb25fZGF0YSkgJT4lICMgdG8gZ2V0IHRoZSBwb3B1bGF0aW9uIG9mIHRob3NlIGFnZWQgMTYtMzQgeWVhcnMgDQogIGdyb3VwX2J5KGhiX25hbWUpICU+JSANCiAgbXV0YXRlKHByb3BfeW91bmdfcHBsX2hiID0gcG9wX2hiXzE2XzM0L2hiX3BvcHVsYXRpb24pICU+JSAjIGNhbGN1bGF0ZSBwcm9wb3J0aW9uIG9mIHlvdW5nIHBlb3BsZSBpbiBlYWNoIGhlYWx0aCBib2FyZCANCiAgdW5ncm91cCgpDQpgYGANCg0KUGxvdCB0YWJsZSAxOg0KYGBge3IgYW5udWFsX3RhYmxlLCBmaWcuY2FwPSgiVGFibGUgMTogQXZlcmFnZSBBbm51YWwgUmF0ZSBvZiBFbWVyZ2VuY3kgQ29udHJhY2VwdGlvbiBQcmVzY3JpcHRpb25zIGJ5IEhlYWx0aCBCb2FyZCBSZWdpb24gaW4gU2NvdGxhbmQuIil9DQphbm51YWxfYXZnX0VDUF90YWJsZSA8LSBFQ1BfYW51YWxfcmF0ZV9kYXRhX3lvdW5nICU+JSANCiAgc2VsZWN0KGhiX25hbWUsIGxldm9ub3JnZXN0cmVsX3JhdGUsIHVsaXByaXN0YWxfYWNldGF0ZV9yYXRlLCB0b3RhbF9FQ1BfcmF0ZSxwcm9wX3lvdW5nX3BwbF9oYikgJT4lICMgU2VsZWN0IHJlbGV2YW50IGNvbHVtbnMNCiAgZ3QoKSAlPiUgDQogIGNvbHNfbGFiZWwoaGJfbmFtZSA9ICJIZWFsdGggQm9hcmQiLA0KICAgICAgICAgICAgIHRvdGFsX0VDUF9yYXRlPSAiVG90YWwiLA0KICAgICAgICAgICAgIGxldm9ub3JnZXN0cmVsX3JhdGU9ICIgTGV2b25vcmdlc3RyZWwiLA0KICAgICAgICAgICAgIHVsaXByaXN0YWxfYWNldGF0ZV9yYXRlPSIgVWxpcHJpc3RhbCBBY2V0YXRlIiwNCiAgICAgICAgICAgICBwcm9wX3lvdW5nX3BwbF9oYiA9ICIlIEFnZWQgMTYtMzQgWWVhcnMiKSAlPiUgIyByZW5hbWUgY29sdW1ucyB0byBtYWtlIHJlYWRlci1mcmllbmRseQ0KICBmbXRfbnVtYmVyKGNvbHVtbnMgPSBjKGxldm9ub3JnZXN0cmVsX3JhdGUsIHVsaXByaXN0YWxfYWNldGF0ZV9yYXRlLCB0b3RhbF9FQ1BfcmF0ZSwgcHJvcF95b3VuZ19wcGxfaGIpLCBkZWNpbWFscyA9IDApICU+JSAjIG5vIGRlY2ltYWwgcG9pbnRzIGFzIGZhbHNlIGFjY3VyYWN5IGRldHJhY3RzIGZyb20gdGhlIG1lc3NhZ2UgaW4gdGhlIGRhdGENCiAgY29sc19hbGlnbihhbGlnbiA9ICJjZW50ZXIiLCBjb2x1bW5zID0gYyhsZXZvbm9yZ2VzdHJlbF9yYXRlLHVsaXByaXN0YWxfYWNldGF0ZV9yYXRlLHRvdGFsX0VDUF9yYXRlLCBwcm9wX3lvdW5nX3BwbF9oYikpICU+JSAgIyBjZW50cmUgY29sdW1uIG5hbWVzDQogIGdyYW5kX3N1bW1hcnlfcm93cyhjb2x1bW5zID0gYyhsZXZvbm9yZ2VzdHJlbF9yYXRlLHVsaXByaXN0YWxfYWNldGF0ZV9yYXRlLCB0b3RhbF9FQ1BfcmF0ZSksIGZucyA9IGxpc3QoIk92ZXJhbGwgQXZlcmFnZSIgPSB+bWVhbiguLCBuYS5ybSA9IFRSVUUpKSwgZm10ID0gbGlzdCh+IGZtdF9udW1iZXIoLiwgZGVjaW1hbHMgPSAwKSkpICU+JSAjIGFkZCBhbiBvdmVyYWxsIGF2ZXJhZ2UgZm9yIHRoZSByYXRlIGNvbHVtbnMNCiAgZm10X3BlcmNlbnQoY29sdW1ucyA9IHByb3BfeW91bmdfcHBsX2hiLCBkZWNpbWFscyA9IDApICU+JSAgIyBhZGQgcGVyY2VudGFnZSBzaWduDQogIHRhYl9oZWFkZXIodGl0bGUgPSBtZCgiKipBdmVyYWdlIEFubnVhbCBSYXRlIG9mIEVtZXJnZW5jeSBDb250cmFjZXB0aW9uIFByZXNjcmlwdGlvbnMgYnkgSGVhbHRoIEJvYXJkIGluIFNjb3RsYW5kLioqIiksDQogICAgICAgICAgICAgc3VidGl0bGUgPSBtZCgiUmF0ZSBwZXIgMTAwLDAwMCB3b21lbiwgZGVyaXZlZCBmcm9tIHRoZSBtZWFuIHByZXNjcmlwdGlvbiByYXRlcyBhY3Jvc3MgdGhlIHllYXJzIDIwMTkgdG8gMjAyMi4gSGVhbHRoIEJvYXJkcyBhcmUgcmFua2VkIGluIGRlc2NlbmRpbmcgb3JkZXIuIikpICU+JSAjIGFkZCBhIHRpdGxlIGFuZCBzdWJ0aXRsZTsgbWQoKSBhbGxvd3MgdGV4dCBmb3JtYXR0aW5nIGZyb20gbWFyayBkb3duIA0KICB0YWJfc3Bhbm5lcihsYWJlbCA9IG1kKCIqUHJlc2NyaXB0aW9uIHJhdGUgcGVyIDEwMCwwMDAgd29tZW4qIiksIGNvbHVtbnMgPSBjKGxldm9ub3JnZXN0cmVsX3JhdGUsdWxpcHJpc3RhbF9hY2V0YXRlX3JhdGUsIHRvdGFsX0VDUF9yYXRlKSkgJT4lICMgYWRkIGEgdGl0bGUgdG8gdGhlIHJhdGUgY29sdW1ucy4NCiAgdGFiX3NvdXJjZV9ub3RlKG1kKCIqRGF0YSBmcm9tIFB1YmxpYyBIZWFsdGggU2NvdGxhbmQuIEF2YWlsYWJsZSBmcm9tOiAoaHR0cHM6Ly93d3cub3BlbmRhdGEubmhzLnNjb3QvZGF0YXNldC9wcmVzY3JpcHRpb25zLWluLXRoZS1jb21tdW5pdHkpKiIpKSAlPiUgDQogIHRhYl9zdHViaGVhZChtZCgiKioyMDE5LTIwMjIqKiIpKSAlPiUgDQogIHRhYl9mb290bm90ZShmb290bm90ZSA9ICJpbmNsdWRlcyBDYXBpdGFsIENpdHksIEVkaW5idXJnaCIsIGxvY2F0aW9ucyA9IGNlbGxzX2JvZHkoY29sdW1ucyA9IGhiX25hbWUsIHJvd3MgPSAyKSklPiUgDQogIG9wdF9zdHlsaXplKHN0eWxlID0gNiwgY29sb3IgPSAiYmx1ZSIpDQoNCmFubnVhbF9hdmdfRUNQX3RhYmxlDQpgYGANCg0KVGFibGUgMSBwcmVzZW50cyB0aGUgYW5udWFsIHByZXNjcmlwdGlvbiByYXRlIG9mIEVDUCBwZXIgSGVhbHRoIEJvYXJkLCBhbG9uZ3NpZGUgdGhlIHByb3BvcnRpb24gb2YgeW91bmcgcGVvcGxlIGxpdmluZyBpbiBlYWNoIEhlYWx0aCBCb2FyZC4gDQoNCktleSBwb2ludHMgdG8gbm90ZToNCg0KKiAqKk5IUyBHcmVhdGVyIEdsYXNnb3cgYW5kIENseWRlIGFuZCBOSFMgTG90aGlhbiBoYXZlIHRoZSBoaWdoZXN0IGFubnVhbCBFQ1AgcHJlc2NyaXB0aW9uIHJhdGUuKiogVGhlc2UgcmVnaW9ucyBlbmNvbXBhc3MgU2NvdGxhbmQncyBsYXJnZXN0IGNpdGllcywgR2xhc2dvdyBhbmQgRWRpbmJ1cmdoLCB3aGljaCBtYXkgY29udHJpYnV0ZSB0byBoaWdoZXIgZGVtYW5kIGZvciBFQ1Agc2VydmljZXMuDQoNCiogKipIZWFsdGggYm9hcmRzIHdpdGggaGlnaGVyIEVDUCBwcmVzY3JpcHRpb24gcmF0ZXMgZ2VuZXJhbGx5IGhhdmUgYSBoaWdoZXIgcHJvcG9ydGlvbiBvZiB5b3VuZyBwZW9wbGUuKiogVGhpcyBzdWdnZXN0cyB0aGF0IHlvdW5nIHBlb3BsZSBhZ2VkIDE2IHRvIDM0IHllYXJzIGFyZSBtb3JlIGxpa2VseSB0byByZXF1aXJlIGVtZXJnZW5jeSBjb250cmFjZXB0aW9uLCBpbiBrZWVwaW5nIHdpdGggY3VycmVudCBsaXRlcmF0dXJlICg1KS4gDQoNCiogKipOSFMgQXlyc2hpcmUgYW5kIEFycmFuIGlzIGFuIG91dGxpZXIuKiogRGVzcGl0ZSBoYXZpbmcgdGhlIHRoaXJkIGhpZ2hlc3QgRUNQIHByZXNjcmlwdGlvbiByYXRlLCBpdCBoYXMgYSByZWxhdGl2ZWx5IHNtYWxsZXIgcG9wdWxhdGlvbiBvZiB5b3VuZyBwZW9wbGUgKDE5JSkuIFRoaXMgd2FycmFudHMgZnVydGhlciBleHBsb3JhdGlvbiwgYXMgaXQgbWF5IGluZGljYXRlIGdyZWF0ZXIgdXNlIG9mIEVDUCBzZXJ2aWNlcyBieSB1bmRlciAxNnMgb3Igb3ZlciAzNXMgaW4gdGhpcyByZWdpb24gaGVscGluZyB0byBndWlkZSB0YXJnZXRlZCBpbnRlcnZlbnRpb25zLiAgDQoNCiogKipSZW1vdGUgYW5kIHJ1cmFsIEhlYWx0aCBCb2FyZHMgc3VjaCBhcyBOSFMgSGlnaGxhbmQgYW5kIE5IUyBCb3JkZXJzIGhhZCB0aGUgbG93ZXN0IHJhdGUgb2YgRUNQIHByZXNjcmliaW5nLioqIFRoZXkgYWxzbyBoYWQgYSBzbWFsbGVyIHByb3BvcnRpb24gb2YgeW91bmcgcGVvcGxlIGxpdmluZyBpbiB0aGVpciBoZWFsdGggYm9hcmQsIHdoaWNoIG1heSBleHBsYWluIHRoaXMgb2JzZXJ2YXRpb24uDQoNCiogKipMZXZvbm9yZ2VzdHJlbCBpcyBtb3JlIGNvbW1vbmx5IHByZXNjcmliZWQgdGhhbiBVbGlwcmlzdGFsIEFjZXRhdGUgYWNyb3NzIG1vc3QgSGVhbHRoIEJvYXJkcy4qKiBIb3dldmVyLCBpbiB0aGUgTkhTIFdlc3Rlcm4gSXNsZXMgSGVhbHRoIEJvYXJkIHRoZSBwcmVzY3JpYmluZyByYXRlcyBmb3IgTGV2b25vcmdlc3RyZWwgYW5kIFVsaXByaXN0YWwgQWNldGF0ZSBhcmUgbmVhcmx5IGVxdWFsIFRoaXMgdmFyaWF0aW9uIG1heSByZWZsZWN0IGRpc3Bhcml0aWVzIGluIHByZXNjcmliaW5nIHByYWN0aWNlcyBiZXR3ZWVuIEhlYWx0aCBCb2FyZHMuIFRoaXMgaXMgZXhwbG9yZWQgZnVydGhlciBpbiBmaWd1cmUgMy4NCg0KIyMgQXJlIHBoYXJtYWNpZXMgaW4gbW9yZSBkZXByaXZlZCBhcmVhcyBwcmVzY3JpYmluZyBtb3JlIEVDUCB0aGFuIHRob3NlIGluIGFmZmx1ZW50IGFyZWFzPw0KDQpSZWFkIGluIGFuZCB3cmFuZ2xlIGRhdGE6DQpgYGB7cn0NCiMgVG8gbWVhc3VyZSBkZXByaXZhdGlvbiBJIGhhdmUgdXNlZCB0aGUgU2NvdHRpc2ggSW5kZXggb2YgTXVsdGlwbGUgRGVwcml2YXRpb24uIDIwMjB2MiBkYXRhc2V0IGZyb20gUHVibGljIEhlYWx0aCBTY290bGFuZC4gKGxpbmsgYXZhaWxhYmxlIGluIGNvZGUpDQpTSU1EIDwtIHJlYWRfY3N2KCJodHRwczovL3d3dy5vcGVuZGF0YS5uaHMuc2NvdC9nbC9kYXRhc2V0Lzc4ZDQxZmE5LTFhNjItNGY3Yi05ZWRiLTNlODUyMmE5MzM3OC9yZXNvdXJjZS9hY2FkZTM5Ni04NDMwLTRiMzQtODk1YS1iM2U3NTdmYTM0NmUvZG93bmxvYWQvc2ltZDIwMjB2Ml8yMjA2MjAyMC5jc3YiKSAlPiUNCiAgY2xlYW5fbmFtZXMoKSAlPiUNCiAgc2VsZWN0KGRhdGFfem9uZSwgc2ltZDIwMjB2MmhiX2RlY2lsZSkNCg0KIyBJIGNob3NlIHRvIHVzZSBHUCBQcmFjdGljZXMgYW5kIExpc3QgU2l6ZXMgZnJvbSBPY3RvYmVyIDIwMjIsIGFzIHRoaXMgd2FzIHRoZSBjbG9zZXN0IGRhdGFzZXQgSSBjb3VsZCBmaW5kIHdoaWNoIGNvcnJlbGF0ZWQgd2l0aCB0aGUgZmluYWwgeWVhciBvZiBteSBwcmVzY3JpcHRpb25zIGRhdGFzZXQ6DQpncF9hZGRyZXNzZXMgPC0gcmVhZF9jc3YoImh0dHBzOi8vd3d3Lm9wZW5kYXRhLm5ocy5zY290L2RhdGFzZXQvZjIzNjU1YzMtNmUyMy00MTAzLWE1MTEtYTgwZDk5OGFkYjkwL3Jlc291cmNlLzFhMTVjYjM0LWZjZjktNGQzZi1hZDYzLTFiYTNlNjc1ZmJlMi9kb3dubG9hZC9wcmFjdGljZV9jb250YWN0ZGV0YWlsc19vY3QyMDIyLW9wZW4tZGF0YS5jc3YiKSAlPiUNCiAgY2xlYW5fbmFtZXMoKSAlPiUNCiAgc2VsZWN0KHByYWN0aWNlX2NvZGUsIGdwX3ByYWN0aWNlX25hbWUsIGRhdGFfem9uZSkNCg0KIyBDcmVhdGUgRUNQX0dQIGJ5IHVzaW5nIHRoZSBHUF9hZGRyZXNzZXMgZGF0YXNldCB0byBtYXAgdGhlIEdQIHByYWN0aWNlIGNvZGUgdG8gYSBkYXRhem9uZS4gSSB0aGVuIHVzZWQgdGhlIGNvbHVtbiBkYXRhem9uZSB0byBmdWxsX2pvaW4oKSB0aGUgU0lNRCBkYXRhc2V0IHRvIHRoZSBwcmVzY3JpcHRpb25zIGRhdGFzZXQuDQpFQ1BfR1AgPC0gRUNQX3NjcmlwdHMgJT4lDQogIGZpbHRlcighZ3BfcHJhY3RpY2UgJWluJSBjKDk5OTk2LCA5OTk5NywgOTk5OTgpKSAlPiUgIyByZW1vdmUgZHVtbXkgR1AgcHJhY3RpY2UgY29kZXMgYXMgdGhleSBkbyBub3QgaGF2ZSBhIGtub3duIGdwIHByYWN0aWNlIGNvZGUgc28gY2Fubm90IGJlIG1hcHBlZCB0byBhIFNJTUQuDQogIGxlZnRfam9pbihncF9hZGRyZXNzZXMsIGJ5ID0gYygiZ3BfcHJhY3RpY2UiID0gInByYWN0aWNlX2NvZGUiKSkgJT4lDQogICNsZWZ0X2pvaW4oZGF0YV96b25lcywgYnkgPSAiZGF0YV96b25lIikgJT4lDQogIGxlZnRfam9pbihTSU1ELCBieSA9ICJkYXRhX3pvbmUiKSAlPiUNCiAgZHJvcF9uYShzaW1kMjAyMHYyaGJfZGVjaWxlKSAlPiUgIyBuZWVkIFNJTUQgdmFsdWUgdG8gZm9yIHBsb3QNCiAgZ3JvdXBfYnkoZ3BfcHJhY3RpY2UpICU+JSANCiAgbXV0YXRlKHRvdGFsX3F1YW50aXR5X3Blcl9ncCA9IHN1bShwYWlkX3F1YW50aXR5KSkgJT4lIA0KICBjbGVhbl9uYW1lcygpDQoNCiMgY2FsY3VsYXRlIHRoZSBudW1iZXIgb2YgR1BzIHBlciBTSU1EIChhY2NvdW50IGZvciBlYWNoIFNJTUQgaGF2aW5nIGEgZGlmZmVyZW50IG51bWJlciBvZiBHUHMpIA0KdG9hbF9ub19HUF9wZXJfU0lNRCA8LSBFQ1BfR1AgJT4lIA0KICBncm91cF9ieShzaW1kMjAyMHYyaGJfZGVjaWxlKSAlPiUNCiAgbXV0YXRlKHVuaXF1ZV9ncF9jb3VudF9wZXJfU0lNRCA9IG5fZGlzdGluY3QoZ3BfcHJhY3RpY2UpKQ0KYGBgDQoNClBsb3QgZmlndXJlIDI6DQpgYGB7ciBTSU1EX2ZpZ3VyZSwgZmlnLmNhcD0oIkZpZ3VyZSAyOiBJbnRlcmFjdGl2ZSBCYXJjaGFydCBzaG93aW5nIEVtZXJnZW5jeSBDb250cmFjZXB0aW9uIFByZXNjcmlwdGlvbnMgYnkgU2NvdHRpc2ggSW5kZXggb2YgTXVsdGlwbGUgRGVwcml2YXRpb24gKFNJTUQpLiIpfQ0KRUNQX1NJTURfYmFyY2hhcnQgPC0gdG9hbF9ub19HUF9wZXJfU0lNRCAlPiUNCiAgZ3JvdXBfYnkoc2ltZDIwMjB2MmhiX2RlY2lsZSwgZHJ1ZykgJT4lIA0KICBzdW1tYXJpc2UocHJlc2NyaXB0aW9uc19ncCA9ICh0b3RhbF9xdWFudGl0eV9wZXJfZ3AgLyB1bmlxdWVfZ3BfY291bnRfcGVyX1NJTUQpLCAjIGNhbGN1bGF0ZSB0aGUgcHJlc2NyaXB0aW9ucyBwZXIgR1AgZm9yIGVhY2ggU0lNRCBkZWNpbGUgYW5kIGRydWcNCiAgICAuZ3JvdXBzID0gImRyb3AiKSAlPiUgICMgVW5ncm91cCBkYXRhIGFmdGVyIHN1bW1hcmlzYXRpb24NCiAgZ2dwbG90KGFlcyh4ID0gZmFjdG9yKHNpbWQyMDIwdjJoYl9kZWNpbGUsIGxldmVscyA9IDE6MTApLHkgPSBwcmVzY3JpcHRpb25zX2dwLCAgZmlsbCA9IGRydWcsIHRleHQgPSBwYXN0ZSgiRGVjaWxlOiIsIHNpbWQyMDIwdjJoYl9kZWNpbGUsICI8YnI+RHJ1ZzoiLCBkcnVnKSkpICsgIyBjdXN0b21pc2UgaG92ZXIgYm94IGZvciBpbnRlcmFjdGl2ZSBjaGFydA0KICBnZW9tX2NvbCgpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiIzQ1NzViNCIsICIjOTFiZmRiIiksIG5hbWUgPSAiRHJ1ZyBUeXBlIikgKyAgIyBhZGQgY29sb3VyIHBhbGV0dGUNCiAgbGFicyh0aXRsZSA9ICJFbWVyZ2VuY3kgQ29udHJhY2VwdGlvbiBQcmVzY3JpcHRpb25zIGJ5IFxuIFNjb3R0aXNoIEluZGV4IG9mIE11bHRpcGxlIERlcHJpdmF0aW9uIChTSU1EKSAyMDE5IHRvIDIwMjIsIFxuIG5vcm1hbGlzZWQgYnkgbnVtYmVyIG9mIEdQcyBwZXIgU0lNRCBkZWNpbGUuIiwNCiAgICB4ID0gIlNJTUQgRGVjaWxlIFxuICgxID0gTW9zdCBEZXByaXZlZCwgMTAgPSBMZWFzdCBEZXByaXZlZCkiLA0KICAgIHkgPSAiVG90YWwgUHJlc2NyaXB0aW9ucyIsDQogICAgZmlsbCA9ICJEcnVnIikgKw0KICB0aGVtZV9taW5pbWFsKGJhc2Vfc2l6ZSA9IDEyKSArDQogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0LCBmYWNlID0gImJvbGQiLCBoanVzdCA9IDAuNSksDQogICAgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIsIGhqdXN0ID0gMC41KSwNCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwNCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwNCiAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGhqdXN0ID0gMSksDQogICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwNCiAgICBsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiLA0KICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIsIGZhY2UgPSAiYm9sZCIpLA0KICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCkpDQoNCkVDUF9TSU1EX2JhcmNoYXJ0IDwtIGdncGxvdGx5KEVDUF9TSU1EX2JhcmNoYXJ0LCB0b29sdGlwID0gInRleHQiKSAjIG1ha2UgcGxvdCBpbnRlcmFjdGl2ZQ0KRUNQX1NJTURfYmFyY2hhcnQNCmBgYA0KDQpHZW5lcmFsbHkgYXMgU0lNRCBkZWNpbGUgaW5jcmVhc2VzIHRoZSBudW1iZXIgb2YgRUNQIHByZXNjcmlwdGlvbnMgZGVjcmVhc2VzLiBHUHMgaW4gU0lNRDEsIHRoZSBtb3N0IGRlcHJpdmVkIGFyZWFzLCBwcmVzY3JpYmUgdGhlIG1vc3QgRUNQLCB3aGlsc3QgaW5jcmVhc2luZyBhZmZsdWVuY2UgaXMgYXNzb2NpYXRlZCB3aXRoIGEgZGVjbGluZSBpbiBFQ1AgcHJlc2NyaXB0aW9ucy4gVGhpcyBzdWdnZXN0cyB0aGF0IGluZGl2aWR1YWxzIGZyb20gbW9yZSBkZXByaXZlZCBhcmVhcyB1dGlsaXNlIEVDUCBzZXJ2aWNlcyBtb3JlIGZyZXF1ZW50bHksIGhpZ2hsaWdodGluZyBhIHBvdGVudGlhbCBpbmVxdWFsaXR5IGluIGhlYWx0aCBuZWVkcy4gDQoNClRoaXMgZGlzcGFyaXR5IG1heSBiZSBkdWUgdG8gZmFjdG9ycyBzdWNoIGFzIGVkdWNhdGlvbiwgYXdhcmVuZXNzIG9mIHNhZmUgc2V4dWFsIHByYWN0aWNlcywgZW52aXJvbm1lbnRhbCBpbmZsdWVuY2VzLCBvciBsaW1pdGVkIGFjY2VzcyB0byBsb25nLWFjdGluZyByZXZlcnNpYmxlIGNvbnRyYWNlcHRpb24gKExBUkMpLiBGdXJ0aGVyIGludmVzdGlnYXRpb24gaW50byB0aGVzZSBmYWN0b3JzIGlzIGVzc2VudGlhbCB0byBhZGRyZXNzIHRoaXMgaW5lcXVhbGl0eS4gDQoNCiMjIElzIHRoZXJlIGdlb2dyYXBoaWNhbCB2YXJpYXRpb24gaW4gdGhlIHByZXNjcmliaW5nIHByYWN0aWNlcyBvZiBFQ1AgYnkgSGVhbHRoIEJvYXJkIHJlZ2lvbj8NCg0KVGhpcyBhbmFseXNpcyBleHBsb3JlcyBpZiB0aGVyZSB3YXMgYW55IGNvcnJlbGF0aW9uIGJldHdlZW4gdGhlIHR5cGUgb2YgY29udHJhY2VwdGlvbiBwcmVzY3JpYmVkIGFuZCB0aGUgbG9jYXRpb24gb2YgdGhlIHBoYXJtYWN5LiBUaGUgcmF0aW8gb2YgdG90YWwgTGV2b25vcmdlc3RyZWwgcHJlc2NyaXB0aW9ucyB0byB0b3RhbCBlbWVyZ2VuY3kgY29udHJhY2VwdGlvbiBwcmVzY3JpcHRpb25zIHdhcyBjYWxjdWxhdGVkIGZvciBlYWNoIEhlYWx0aCBCb2FyZCBSZWdpb24gdXNpbmcgdGhlIGZvcm11bGE6DQoNCiQkDQpcZnJhY3tMZXZvbm9yZ2VzdHJlbH17TGV2b25vcmdlc3RyZWwgKyBVbGlwcmlzdGFsIEFjZXRhdGV9ID0gUmF0aW8NCiQkDQoNCkEgc2NvcmUgY2xvc2UgdG8gMSBpbmRpY2F0ZXMgdGhhdCB0aGUgbWFqb3JpdHkgb2YgcHJlc2NyaXB0aW9ucyBpbiB0aGlzIHJlZ2lvbiBhcmUgZm9yIExldm9ub3JnZXN0cmVsLCB3aGlsc3QgYSBzY29yZSBjbG9zZXIgdG8gMCBzdWdnZXN0cyB0aGF0IHRoZSBtYWpvcml0eSBvZiBwcmVzY3JpcHRpb25zIGFyZSBVbGlwcmlzdGFsIEFjZXRhdGUuIFRoaXMgYXBwcm9hY2ggcHJvdmlkZXMgYSB1c2VmdWwgd2F5IG9mIGlkZW50aWZ5aW5nIHZhcmlhdGlvbiBpbiBwcmVzY3JpYmluZyBwcmFjdGljZXMuIA0KDQpGaWd1cmUgMzoNCmBgYHtyIGdlb2dfZmlndXJlLCBmaWcuY2FwPSAoIkZpZ3VyZSAzOiBIZWF0bWFwIGV4cGxvcmluZyBnZW9ncmFwaGljYWwgdmFyaWF0aW9uIGluIEVtZXJnZW5jeSBDb250cmFjZXB0aW9uIFBpbGwgcHJlc2NyaWJpbmciKX0NCiMgbG9hZCB0aGUgTkhTIEhlYWx0aCBib2FyZCBTaGFwZWZpbGUgZG93bmxvYWRlZCBmcm9tIGxlYXJuIHBhZ2UNCk5IU19oZWFsdGhib2FyZHMgPC0gc3RfcmVhZChoZXJlKCJkYXRhIiwgIk5IU19oZWFsdGhib2FyZHNfMjAxOS5zaHAiKSkgJT4lIA0KICBtdXRhdGUoSEJOYW1lID0gcGFzdGUoIk5IUyIsIEhCTmFtZSkpICU+JSAjIGZvcm1hdCB0byBtYXRjaCBFQ1Bfc2NyaXB0cyBkYXRhc2V0DQogIGNsZWFuX25hbWVzKCkNCg0KIyBjYWxjdWxhdGUgdGhlIHJhdGlvIG9mIExldiB0byBVbGkgcHJlc2NyaWJlZCANCnZhcmlhdGlvbl9FQ1BfcHJlc2NyaWJlZCA8LSBFQ1Bfc2NyaXB0cyAlPiUgDQogIGdyb3VwX2J5KGhiX25hbWUsZHJ1ZykgJT4lIA0KICAjIGNhbGN1bGF0ZSB0aGUgdG90YWwgb2YgTGV2IGFuZCBVbGkgcHJlc2NyaWJlZCBwZXIgaGVhbHRoIGJvYXJkDQogIHN1bW1hcmlzZSh0b3RhbF9lYWNoX2RydWdfdHlwZSA9IHN1bShwYWlkX3F1YW50aXR5LCBuYS5ybSA9IFRSVUUpKSAlPiUNCiAgZHJvcF9uYShkcnVnKSAlPiUgDQogICNwaXZvdF93aWRlciB0byBtb3ZlIGRydWcgbmFtZXMgdG8gY29sdW1ucyANCiAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IGRydWcsIHZhbHVlc19mcm9tID0gdG90YWxfZWFjaF9kcnVnX3R5cGUpICU+JQ0KICBjbGVhbl9uYW1lcygpICU+JSAjIGNvbnNpc3RlbmN5IA0KICBtdXRhdGUobGV2b190b191bGlfcmF0aW8gPSBsZXZvbm9yZ2VzdHJlbCAvIChsZXZvbm9yZ2VzdHJlbCArIHVsaXByaXN0YWxfYWNldGF0ZSkpICMgY2FsY3VsYXRlIHJhdGlvIA0KDQojIEpvaW4gc3BhdGlhbCBkYXRhIHdpdGggdmFyaWF0aW9uX0VDUF9wcmVzY3JpYmVkDQp2YXJpYXRpb25fRUNQX3ByZXNjcmliZWQgPC0gTkhTX2hlYWx0aGJvYXJkcyAlPiUNCiAgbGVmdF9qb2luKHZhcmlhdGlvbl9FQ1BfcHJlc2NyaWJlZCkNCg0KI0NyZWF0ZSBtYXAgaW4gZ2dwbG90DQptYXBfdmFyaWF0aW9uX0VDUF9wcmVzY3JpYmVkIDwtIHZhcmlhdGlvbl9FQ1BfcHJlc2NyaWJlZCAlPiUNCiAgZ2dwbG90KGFlcyhmaWxsID0gbGV2b190b191bGlfcmF0aW8pKSArDQogIGdlb21fc2Yoc2l6ZSA9IDAuMSwgY29sb3VyID0gImdyZXk1MCIsIGFscGhhID0wLjkpICsNCiAgc2NhbGVfZmlsbF9kaXN0aWxsZXIocGFsZXR0ZSA9ICJCbHVlcyIsIGRpcmVjdGlvbiA9IDEpICsNCiAgbGFicyh0aXRsZSA9ICJHZW9ncmFwaGljYWwgdmFyaWF0aW9uIGluIEVtZXJnZW5jeSBDb250cmFjZXB0aXZlIFxuIFBpbGwgcHJlc2NyaWJpbmcgaW4gU2NvdGxhbmQuIiwgDQogICAgICAgc3VidGl0bGUgPSAiSGVhdG1hcCBzaG93aW5nIExldm9ub3JnZXN0cmVsIHByZXNjcmlwdGlvbnMgYXMgYSBwcm9wb3J0aW9uIG9mIHRvdGFsIFxuIEVtZXJnZW5jeSBDb250cmFjZXB0aXZlIFBpbGwgKEVDUCkgcHJlc2NyaXB0aW9ucyBieSBIZWFsdGggQm9hcmQgcmVnaW9uIiwgDQogICAgICAgZmlsbCA9ICJMZXZvbm9yZ2VzdHJlbCB0byBFQ1AgcmF0aW8iLCBjYXB0aW9uID0gIkRhdGEgU291cmNlOiBQdWJsaWMgSGVhbHRoIFNjb3RsYW5kIFByZXNjcmlwdGlvbnMgaW4gdGhlIENvbW11bml0eSwgMjAxOS0yMDIyIikgKw0KICBjb29yZF9zZigpICsNCiAgdGhlbWVfdm9pZCgpICsNCiAgdGhlbWUoDQogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiLCBzaXplID0gMTgsIGhqdXN0PTAuNSksIA0KICAgIHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0LCBoanVzdD0wLjUpLCANCiAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwNCiAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gOSwgaGp1c3Q9MC41KSwNCiAgICBsZWdlbmQuZGlyZWN0aW9uID0gInZlcnRpY2FsIiwNCiAgICBsZWdlbmQuYm94ID0gImhvcml6b250YWwiKSArDQogIGFubm90YXRpb25fc2NhbGUobG9jYXRpb24gPSAidGwiKSArDQogIGFubm90YXRpb25fbm9ydGhfYXJyb3coDQogICAgbG9jYXRpb24gPSAidGwiLCAgICANCiAgICBwYWRfeSA9IHVuaXQoMC41LCAiaW4iKSwgICAgDQogICAgc3R5bGUgPSBub3J0aF9hcnJvd19uYXV0aWNhbChmaWxsID0gYygiZ3JleTQwIiwgIndoaXRlIiksbGluZV9jb2wgPSAiZ3JleTIwIikpDQoNCm1hcF92YXJpYXRpb25fRUNQX3ByZXNjcmliZWQNCmBgYA0KDQpIZWFsdGggQm9hcmQgUmVnaW9ucyBpbiBjZW50cmFsIFNjb3RsYW5kIHByZWRvbWluYW50bHkgcHJlc2NyaWJlIExldm9ub3JnZXN0cmVsLCB3aGVyZSBhcyBtb3JlIHJlbW90ZSBhbmQgcnVyYWwgSGVhbHRoIEJvYXJkIHJlZ2lvbnMsIHN1Y2ggYXMgdGhlIE5IUyBXZXN0ZXJuIElzbGVzLCBwcmVzY3JpYmUgaGlnaGVyIHByb3BvcnRpb25zIG9mIFVsaXByaXN0YWwgQWNldGF0ZS4gVGhpcyBkaWZmZXJlbmNlIGluIHByZXNjcmliaW5nIHByYWN0aWNlcyBtYXkgcmVmbGVjdCBkaXNwYXJpdGllcyBpbiBhY2Nlc3MgdG8gZW1lcmdlbmN5IGNvbnRyYWNlcHRpb24gaW4gcmVtb3RlIGFuZCBydXJhbCByZWdpb25zLiBQYXRpZW50cyBpbiB0aGVzZSByZWdpb25zIG1heSBwcmVzZW50IGxhdGVyIHRvIGhlYWx0aCBzZXJ2aWNlcyBsYXRlciwgcHJvbXB0aW5nIHByZXNjcmliZXJzIHRvIGRpc3BlbnNlIFVsaXByaXN0YWwgQWNldGF0ZSBkdWUgdG8gaXRzIGxvbmdlciBlZmZpY2FjeSB3aW5kb3cuIEFsdGVybmF0aXZlbHksIHRoaXMgdmFyaWF0aW9uIGNvdWxkIGJlIGF0dHJpYnV0ZWQgdG8gZGlmZmVyZW5jZXMgaW4gcHJlc2NyaWJlciBwcmVmZXJlbmNlcyBvciBndWlkZWxpbmVzIGluIG1vcmUgcmVtb3RlIGFyZWFzLg0KDQojIENvbmNsdXNpb24gDQoNClByZXNjcmlwdGlvbnMgb2YgZW1lcmdlbmN5IGNvbnRyYWNlcHRpdmUgcGlsbHMgKEVDUCkgaGF2ZSBkZWNyZWFzZWQgb3ZlciB0aGUgeWVhcnMgMjAxOSB0byAyMDIyLiBJbiAyMDIwLCB0aGVyZSB3YXMgYSBub3RhYmxlIHJlZHVjdGlvbiBpbiBMZXZvbm9yZ2VzdHJlbCBwcmVzY3JpcHRpb25zLCBsaWtlbHkgaW5mbHVlbmNlZCBieSB0aGUgQ292aWQtMTkgbG9ja2Rvd24uIFVsaXByaXN0YWwgQWNldGF0ZSBoYWQgYSBtYXJrZWQgZGVjbGluZSBmcm9tIDIwMTkgb253YXJkcyBsaWtlbHkgcmVmbGVjdGluZyB1cGRhdGVkIHByZXNjcmliaW5nIGd1aWRhbmNlLCB3aGljaCBkaXNjb250aW51ZWQgaXRzIHVzZSBpbiB0aGUgdHJlYXRtZW50IG9mIHV0ZXJpbmUgZmlicm9pZHMuDQoNCkhlYWx0aCBCb2FyZCByZWdpb25zIHdpdGggbGFyZ2VyIHBvcHVsYXRpb25zIG9mIHlvdW5nIHBlb3BsZSBhbmQgbWFqb3IgY2l0aWVzIGhhZCBoaWdoZXIgcmF0ZXMgb2YgRUNQIHByZXNjcmlwdGlvbnMsIHdoaWxzdCBtb3JlIHJlbW90ZSByZWdpb25zIHdpdGggYSBzbWFsbGVyIHByb3BvcnRpb24gb2YgeW91bmcgcGVvcGxlIGhhZCBhIGxvd2VyIEVDUCBwcmVzY3JpcHRpb24gcmF0ZS4gDQoNCkVDUCBwcmVzY3JpcHRpb25zIHdlcmUgbW9yZSBwcmV2YWxlbnQgaW4gYXJlYXMgb2YgZ3JlYXRlciBkZXByaXZhdGlvbi4NCg0KR2VvZ3JhcGhpY2FsbHksIHJlbW90ZSBwaGFybWFjaWVzIGFwcGVhcmVkIHRvIHByZXNjcmliZSBoaWdoZXIgcHJvcG9ydGlvbnMgb2YgVWxpcHJpc3RhbCBBY2V0YXRlLiBUaGlzIG1heSBiZSBkdWUgdG8gY2hhbGxlbmdlcyBpbiBhY2Nlc3NpbmcgcGhhcm1hY2llcyB3aXRoaW4gNDggaG91cnMgb2YgdW5wcm90ZWN0ZWQgc2V4LCBuZWNlc3NpdGF0aW5nIHRoZSB1c2Ugb2YgVWxpcHJpc3RhbCBBY2V0YXRlLCB3aGljaCBoYXMgYSBsb25nZXIgZWZmaWNhY3kgd2luZG93Lg0KDQpJbiBjb25jbHVzaW9uLCBFQ1AgcHJlc2NyaWJpbmcgcGF0dGVybnMgYXJlIGluZmx1ZW5jZWQgYnkgbXVsdGlwbGUgZmFjdG9ycyBpbmNsdWRpbmcgc29jaWV0YWwgZXZlbnRzIHN1Y2ggYXMgdGhlIENvdmlkLTE5IHBhbmRlbWljLCBhZ2UsIGRlcHJpdmF0aW9uLCBhbmQgZ2VvZ3JhcGh5Lg0KDQojIyBSZWNvbW1lbmRhdGlvbnMgZnJvbSBhbmFseXNpcyANCg0KVGhpcyByZXBvcnQgaGlnaGxpZ2h0cyBzaWduaWZpY2FudCBkaXNwYXJpdGllcyBpbiB0aGUgcHJlc2NyaWJpbmcgb2YgZW1lcmdlbmN5IGNvbnRyYWNlcHRpb24gYWNyb3NzIGRpZmZlcmVudCBnZW9ncmFwaGljIHJlZ2lvbnMgYW5kIGxldmVscyBvZiBkZXByaXZhdGlvbiBpbiBTY290bGFuZC4gRnVydGhlciByZXNlYXJjaCBpcyBuZWVkZWQgdG8gdW5kZXJzdGFuZCB0aGUgdW5kZXJseWluZyBjYXVzZXMgb2YgdGhlc2UgdHJlbmRzLCBjb25zaWRlcmluZyBpZiB0aGVyZSBhcmUgYmFycmllcnMgdG8gYWNjZXNzIG9yIGRpZmZlcmVuY2VzIGluIHByZXNjcmliZXIgcHJhY3RpY2VzLiBUaGVzZSBpbnNpZ2h0cyB3aWxsIGJlIGNydWNpYWwgZm9yIGluZm9ybWluZyBmdXR1cmUgc2V4dWFsIGhlYWx0aCBwb2xpY2llcyBhbmQgaW50ZXJ2ZW50aW9ucyBhaW1lZCBhdCByZWR1Y2luZyBoZWFsdGggaW5lcXVhbGl0aWVzIGFuZCBlbnN1cmluZyBlcXVpdGFibGUgYWNjZXNzIHRvIGVtZXJnZW5jeSBjb250cmFjZXB0aW9uLg0KDQojIyBMaW1pdGF0aW9ucyBvZiB0aGUgZGF0YXNldA0KDQoqIFRoaXMgcmVwb3J0IGFzc3VtZXMgdGhhdCBMZXZvbm9yZ2VzdHJlbCBhbmQgVWxpcHJpc3RhbCBBY2V0YXRlIGFyZSBkaXNwZW5zZWQgZXhjbHVzaXZlbHkgZm9yIGVtZXJnZW5jeSBjb250cmFjZXB0aW9uLCB3aWh0b3V0IGNvbnNpZGVyaW5nIHBvdGVudGlhbCBvZmYtbGljZW5jZSB1c2VzLiANCg0KKiBEaWZmZXJlbmNlcyBpbiB0aGUgdm9sdW1lIG9mIEVDUCBwcmVzY3JpYmVkIGFjcm9zcyBIZWFsdGggQm9hcmRzIG1heSByZXN1bHQgZnJvbSBwYXRpZW50cyBsaXZpbmcgaW4gb25lIEhlYWx0aCBCb2FyZCByZWdpb24gYnV0IG9idGFpbmluZyB0aGVpciBFQ1AgZnJvbSBhIHBoYXJtYWN5IGluIGFub3RoZXIgSGVhbHRoIEJvYXJkIHJlZ2lvbi4gVGhpcyBtYXkgcmVzdWx0IGluIGluYWNjdXJhY2llcyBpbiBhdHRyaWJ1dGluZyBwcmVzY3JpcHRpb24gcmF0ZXMgdG8gc3BlY2lmaWMgSGVhbHRoIEJvYXJkcy4NCg0KKiBUaGUgcHJlc2NyaXB0aW9uIGRhdGFzZXQgaW5jbHVkZWQgJ2R1bW15IHByYWN0aWNlIGNvZGVzJyBmb3IgcHJlc2NyaXB0aW9ucyB3aGljaCBsYWNrZWQgYSBzcGVjaWZpYyBwcmFjdGljZSBjb2RlLiBUaGlzIGV4Y2x1ZGVkIGEgbGFyZ2UgbnVtYmVyIG9mIEVDUCBwcmVzY3JpcHRpb25zIGZyb20gdGhlIEVDUC1kZXByaXZhdGlvbiBhbmFseXNpcyBhcyBpdCB3YXMgaW1wb3NzaWJsZSB0byBsaW5rIHRoZSBwcmVzY3JpcHRpb25zIHRvIGEgZGF0YXpvbmUgYW5kIHN1YnNlcXVlbnQgU0lNRCBkZWNpbGUuIFRoaXMgbWF5IGltcGFjdCB0aGUgYWNjdXJhY3kgb2YgdGhlIGFuYWx5c2lzLg0KDQojIyBTdWdnZXN0aW9ucyBmb3IgZnV0dXJlIGFuYWx5c2lzDQoNCiogV2l0aCBhZGRpdGlvbmFsIHRpbWUgaXQgd291bGQgYmUgaW50ZXJlc3RpbmcgdG8gZGVzaWduIGEgRGlyZWN0ZWQgQWN5Y2xpYyBHcmFwaGljIHRvIHZpc3VhbGx5IGFuZCBtYXRoZW1hdGljYWxseSBtb2RlbCB0aGUgcHJvYmFiaWxpc3RpYyByZWxhdGlvbnNoaXBzIGJldHdlZW4gdmFyaWFibGVzIHN1Y2ggYXMgYWdlLCBkZXByaXZhdGlvbiBhbmQgZ2VvZ3JhcGh5IG9uIEVDUCBwcmVzY3JpYmluZyBwYXR0ZXJucyBpbiBTY290bGFuZC4gDQoNCiogSXQgd291bGQgYmUgaW50ZXJlc3RpbmcgdG8gY29uZHVjdCBzdGF0aXN0aWNhbCBhbmFseXNpcyB0byBleHBsb3JlIHRoZSB0cmVuZHMgaW4gdGhpcyByZXBvcnQuIA0KDQojIFJlZmVyZW5jZXMgDQoNCjEuIAlDbGVsYW5kIEssIFJheW1vbmQgRUcsIFdlc3RsZXkgRSwgVHJ1c3NlbGwgSi4gRW1lcmdlbmN5IGNvbnRyYWNlcHRpb24gcmV2aWV3OiBldmlkZW5jZS1iYXNlZCByZWNvbW1lbmRhdGlvbnMgZm9yIGNsaW5pY2lhbnMuIENsaW4gT2JzdGV0IEd5bmVjb2wgW0ludGVybmV0XS4gMjAxNCBEZWMgW2NpdGVkIDIwMjQgTm92IDI1XTs1Nyg0KTo3NDHigJM1MC4gQXZhaWxhYmxlIGZyb206IGh0dHBzOi8vd3d3Lm5jYmkubmxtLm5paC5nb3YvcG1jL2FydGljbGVzL1BNQzQyMTY2MjUvDQoyLiAJRW1lcmdlbmN5IENvbnRyYWNlcHRpdmUgU3RhdGlzdGljcyAyMDIzIHwgQ2xpY2syUGhhcm1hY3kgW0ludGVybmV0XS4gMjAyMyBbY2l0ZWQgMjAyNCBOb3YgMjVdLiBBdmFpbGFibGUgZnJvbTogaHR0cHM6Ly9jbGljazJwaGFybWFjeS5jby51ay9lbWVyZ2VuY3ktY29udHJhY2VwdGl2ZS1zdGF0aXN0aWNzLTIwMjMvDQozLiAJTG9uZyBBY3RpbmcgUmV2ZXJzaWJsZSBNZXRob2RzIG9mIENvbnRyYWNlcHRpb24gKExBUkMpIGluIFNjb3RsYW5kIC0gWWVhciBlbmRpbmcgMzEgTWFyY2ggMjAyMiAtIExvbmcgQWN0aW5nIFJldmVyc2libGUgQ29udHJhY2VwdGlvbiAoTEFSQykgS2V5IENsaW5pY2FsIEluZGljYXRvciAoS0NJKSAtIFB1YmxpY2F0aW9ucyAtIFB1YmxpYyBIZWFsdGggU2NvdGxhbmQgW0ludGVybmV0XS4gW2NpdGVkIDIwMjQgTm92IDI1XS4gQXZhaWxhYmxlIGZyb206IGh0dHBzOi8vcHVibGljaGVhbHRoc2NvdGxhbmQuc2NvdC9wdWJsaWNhdGlvbnMvbG9uZy1hY3RpbmctcmV2ZXJzaWJsZS1jb250cmFjZXB0aW9uLWxhcmMta2V5LWNsaW5pY2FsLWluZGljYXRvci1rY2kvbG9uZy1hY3RpbmctcmV2ZXJzaWJsZS1tZXRob2RzLW9mLWNvbnRyYWNlcHRpb24tbGFyYy1pbi1zY290bGFuZC15ZWFyLWVuZGluZy0zMS1tYXJjaC0yMDIyLw0KNC4gCVVsaXByaXN0YWwgYWNldGF0ZSA1bWcgbWVkaWNpbmFsIHByb2R1Y3RzIC0gcmVmZXJyYWwgfCBFdXJvcGVhbiBNZWRpY2luZXMgQWdlbmN5IChFTUEpIFtJbnRlcm5ldF0uIDIwMjAgW2NpdGVkIDIwMjQgTm92IDI1XS4gQXZhaWxhYmxlIGZyb206IGh0dHBzOi8vd3d3LmVtYS5ldXJvcGEuZXUvZW4vbWVkaWNpbmVzL2h1bWFuL3JlZmVycmFscy91bGlwcmlzdGFsLWFjZXRhdGUtNW1nLW1lZGljaW5hbC1wcm9kdWN0cw0KNS4gCU1laHRhIFNELCBLdWxrYXJuaSBBRCwgUGF6b2wgSywgS291bWFucyBFSC4gVHJlbmRzIGluIEVtZXJnZW5jeSBDb250cmFjZXB0aXZlIFVzZSBBbW9uZyBBZG9sZXNjZW50cyBhbmQgWW91bmcgQWR1bHRzLCAyMDA24oCTMjAxNy4gSiBBZG9sZXNjIEhlYWx0aCBPZmYgUHVibCBTb2MgQWRvbGVzYyBNZWQgW0ludGVybmV0XS4gMjAyMiBKdWwgW2NpdGVkIDIwMjQgTm92IDI1XTs3MSgxKTo4NuKAkzkzLiBBdmFpbGFibGUgZnJvbTogaHR0cHM6Ly93d3cubmNiaS5ubG0ubmloLmdvdi9wbWMvYXJ0aWNsZXMvUE1DMTA5ODI4NzQvDQoNCg==